-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Description
Description
Currently, mixed materials (e.g. metallic value of 0.5) are not energy conserving and therefore displayed incorrectly.
This issue highlights the error in the glTF spec:
KhronosGroup/glTF#2386
Here you can see the shader refactoring we had to do in the glTF-Sample-Viewer to fix the issue:
KhronosGroup/glTF-Sample-Viewer#556
The issue is clearly visible with the furnace test and mixed materials with iridescence extension (using a premixed F0 has a big impact on the visual output)
Reproduction steps
- Load attached GLBs/HDR
- Compare to glTF-Sample-Viewer output
Furnace test: No spheres should be visible
Iridescence: Changes from left to right should be gradual
iridescence_transmission_metallic_white.zip
Code
This is the old incorrect pseudocode
const black = 0
c_diff = lerp(baseColor.rgb, black, metallic)
f0 = lerp(0.04, baseColor.rgb, metallic)
α = roughness^2
F = f0 + (1 - f0) * (1 - abs(VdotH))^5
f_diffuse = (1 - F) * (1 / π) * c_diff
f_specular = F * D(α) * G(α) / (4 * abs(VdotN) * abs(LdotN))
material = f_diffuse + f_specular
Here is the corrected version:
https://github.com/KhronosGroup/glTF/blob/main/specification/2.0/Specification.adoc#metal-brdf-and-dielectric-brdf
Babylon.js premixes colorReflectanceF0 and uses it e.g. in iridescence:
outParams.colorReflectanceF0 = mix(outParams.dielectricColorF0, metallicColorF0, outParams.metallic); |
Examples
Screenshots from Babylon.js Sandbox:
Screenshots from glTF-Sample-Viewer:
I opened a similar issue for three.js: mrdoob/three.js#31350