three.js
three.js copied to clipboard
MeshPhysicalMaterial should use the thin surface model when thickness is zero
The thin-surface model and the volume model should be separate models in the MeshPhysicalMaterial shader.
Currently, only the volume model is implemented, and if thickness is 0, all components of attenuation color must be non-zero, otherwise the material renders black. A properly-implemented thin-surface model would prevent that.
Maybe define USE_VOLUME if ( .thickness > 0 ). Then something like:
#ifdef USE_TRANSMISSION
#ifdef USE_TRANSMISSIONMAP
transmissionFactor *= texture2D( transmissionMap, vUv ).r;
#endif
#ifdef USE_THICKNESSMAP
thicknessFactor *= texture2D( thicknessMap, vUv ).g;
#endif
#ifdef USE_VOLUME
vec4 transmission = getIBLVolumeRefraction( ... );
#else
vec4 transmission = getIBLThinSurfaceRefraction( ... );
#endif
totalDiffuse = mix( totalDiffuse, transmission.rgb, transmissionFactor );
#endif
three.js version: r.137
Anyone interested in having a go at this?
I can give it a go. Where do I find getIBLThinSurfaceRefraction?
I think it can be inferred by comparing the following two sections:
https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_transmission#implementation-notes
and
https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_volume#implementation.
I haven't tried, however. It's not easy to comprehend -- until, of course, you do. :-)
It'll take me a bit too long to comprehend...
@elalish do you know if any other engine/viewer has already written a getIBLThinSurfaceRefraction?
Babylon is usually pretty quick with supporting glTF extensions; I'd check there. Thin is pretty easy because it means no refraction (your view vector passes straight through to the IBL). The only thing you have to account for is getting the right mip from the roughness, but that should be basically the same as for volume. I believe attenuation color is defined as part of the volume spec, so for thin transmission it's not a thing. Maybe just give it a default (1, 1, 1) value to turn it off?
/ping @donmccurdy ...just in case you are not aware of this...
Thanks @WestLangley! I haven't run into this problem yet in working with MeshPhysicalMaterial, but I agree with your suggestions here. 👍