WebGLRenderer: Add more energy conservation for physically-based materials #32101
+17
−5
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
This PR implements proper energy conservation in the physical lighting model by ensuring that diffuse and specular reflections correctly account for the Fresnel effect.
Previously, the diffuse term did not account for energy taken by specular reflection, causing materials to appear over-bright, especially at grazing angles. This violated the fundamental principle that reflected energy cannot exceed incident energy.
The implementation modifies
RE_Direct_PhysicalandRE_IndirectDiffuse_Physicalto attenuate the diffuse contribution by(1.0 - F), where F is the Fresnel term. This ensures total reflected energy (diffuse + specular) does not exceed incident energy, and diffuse contribution properly decreases as specular increases, particularly at grazing angles.The changes result in more physically accurate rendering, especially for metallic and glossy surfaces. Materials no longer appear over-bright at grazing angles, metals show reduced diffuse at high metalness values, and Fresnel response is more accurate across all viewing angles.
Performance impact is minimal - the implementation reuses the existing Fresnel calculation with one additional multiply per light source.
For comparison:
https://raw.githack.com/mrdoob/three.js/webgl-pbr/examples/index.html