f0 will be infinity when refractionIndex is zero
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 ?