BabylonJS / BabylonJS/Babylon.js

Error in glTF PBR shader

Open
#16,840 13 comments 0 reactions 1 assignee Claimed by @Popov72 View on GitHub
new feature openpbr rendering engine stale
Dominant language
TypeScript
Stars
26.1k
Forks
3.7k
Avg merge
1d 15h
Merged PRs (30d)
73

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:
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](https://github.khronos.org/glTF-Sample-Viewer-Release/) output

Furnace test: No spheres should be visible
Iridescence: Changes from left to right should be gradual

[iridescence_transmission_metallic_white.zip](https://github.com/user-attachments/files/21001670/iridescence_transmission_metallic_white.zip)

[furnace.zip](https://github.com/user-attachments/files/21001758/furnace.zip)

### Code

This is the old incorrect pseudocode
```js
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](https://github.com/user-attachments/assets/737177e9-53c4-4b6b-94b4-e800c05290fc)

![Image](https://github.com/user-attachments/assets/58d10b47-a039-43bf-a4bd-747bece2b298)

Screenshots from glTF-Sample-Viewer:

![Image](https://github.com/user-attachments/assets/e147ec66-3b9b-41d4-af5e-a059d5805035)

![Image](https://github.com/user-attachments/assets/99e13107-4f45-41a1-a262-79b3e296003e)

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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.