engine icon indicating copy to clipboard operation
engine copied to clipboard

f0 will be infinity when refractionIndex is zero

Open scarletsky opened this issue 1 year ago • 0 comments

https://github.com/user-attachments/assets/0ea33fa1-ce62-4d1b-959c-b23d7872726e

PlayCanvas Editor is using v1.73.4.

Let's have a look how refractionIndex works:

StandardMaterialOptionsBuilder#_updateMaterialOptions:

        options.refractionTint = (stdMat.refraction !== 1.0) ? 1 : 0;
        options.refractionIndexTint = (stdMat.refractionIndex !== 1.0 / 1.5) ? 1 : 0;
        options.iorTint = stdMat.refractionIndex !== 1.0 / 1.5 ? 1 : 0;

options.iorTint will pass to ShaderGeneratorStandard#_addMap

        const isFloatTint = !!(tintOption & 1);
        const isVecTint = !!(tintOption & 2);
        const invertOption = !!(options[invertName]);
        subCode = this._addMapDefs(isFloatTint, isVecTint, vertexColorOption, textureOption, invertOption) + subCode;

isFloatTint will replace iorPS's macro:


#ifdef MAPFLOAT
uniform float material_refractionIndex;
#endif

void getIor() {
#ifdef MAPFLOAT
    dIor = material_refractionIndex;
#else
    dIor = 1.0 / 1.5;
#endif
}

In the end, the dIor will be used to calculate f0:

    float f0 = 1.0 / litArgs_ior;
    f0 = (f0 - 1.0) / (f0 + 1.0);
    f0 *= f0;

So when refractionIndex is zero, the f0 = (1.0 / 0.0) = infinity.

Here is the document of refraction

@property {number} refraction Defines the visibility of refraction. Material can refract the same cube map as used for reflections.

If the refraction is zero, the refraction should be invisible. It seems we should let options.iorTint respect refraction ?

-        options.iorTint = stdMat.refractionIndex !== 1.0 / 1.5 ? 1 : 0;
+        options.iorTint = (stdMaterial.refraction > 0 && stdMat.refractionIndex !== 1.0 / 1.5) ? 1 : 0;

Or how should it be ?

scarletsky avatar Sep 05 '24 01:09 scarletsky