Babylon.js icon indicating copy to clipboard operation
Babylon.js copied to clipboard

Error in glTF PBR shader

Open UX3D-haertl opened this issue 5 months ago • 10 comments

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: https://github.com/KhronosGroup/glTF/issues/2386 Here you can see the shader refactoring we had to do in the glTF-Sample-Viewer to fix the issue: https://github.com/KhronosGroup/glTF-Sample-Viewer/pull/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

  1. Load attached GLBs/HDR
  2. 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

furnace.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: https://github.com/BabylonJS/Babylon.js/blob/c869b5bcb55a8f0cc8e0c43949cfc2a196445daf/packages/dev/core/src/Shaders/ShadersInclude/pbrBlockReflectivity.fx#L161

Examples

Screenshots from Babylon.js Sandbox:

Image

Image

Screenshots from glTF-Sample-Viewer:

Image

Image

I opened a similar issue for three.js: https://github.com/mrdoob/three.js/issues/31350

UX3D-haertl avatar Jul 02 '25 08:07 UX3D-haertl

We have a fix for it under a flag which was introduced by @MiiBond ? we can not make it the default for back compat purpose

sebavan avatar Jul 02 '25 20:07 sebavan

I assume this PR https://github.com/BabylonJS/Babylon.js/pull/16476? Seems like this addresses most of the issues. But as far as I have seen it does not change iridescence.

UX3D-haertl avatar Jul 03 '25 13:07 UX3D-haertl

About iridescence, @Popov72 has worked on a fix in the past which should work with what @MiiBond did.

sebavan avatar Jul 03 '25 17:07 sebavan

I tested the assets with legacy energy conservation disabled:

Image Image

All the spheres now have the same color, so the formula for mixing is correct. They are still brighter than the IBL. That might be a different bug.

The iridescence issue does not seem to be fixed by that option, or do I need to toggle another option as well?

UX3D-haertl avatar Jul 11 '25 09:07 UX3D-haertl

This issue has been automatically staled because it has been inactive for more than 14 days. Please update to "unstale".

github-actions[bot] avatar Aug 22 '25 00:08 github-actions[bot]

@Popov72 will have a look when he ll be fully back :-)

sebavan avatar Aug 22 '25 13:08 sebavan

This issue has been automatically staled because it has been inactive for more than 14 days. Please update to "unstale".

github-actions[bot] avatar Sep 20 '25 00:09 github-actions[bot]

cc @Popov72

deltakosh avatar Oct 12 '25 21:10 deltakosh

This will be fixed with the OpenPBR material. Implementation is not yet complete, but if we compare the different results when using a 75% white furnace environment:

Babylon (PBR material): Image

Babylon (OpenPBR material): Image

Sample viewer: Image

We can see we are in the same ballpark with the OpenPBR material as with the sample viewer.

Popov72 avatar Oct 13 '25 08:10 Popov72

I don't have transmission in OpenPBR yet, so that probably accounts for the remaining difference between Babylon and the glTF Sample Viewer.

MiiBond avatar Oct 13 '25 18:10 MiiBond