Reputation: 65
I'm working on learning PBR and Unity standard shader. The really large result from the GGX distribution term confused me.
Unity standard shader uses GGX distribution term:
// I re-write it into C#
private float GGXTerm(float NdotH, float roughness)
{
float a2 = roughness * roughness;
float d = (NdotH * a2 - NdotH) * NdotH + 1.0f;
return a2 / (Mathf.PI * (d * d + 1e-7f));
}
Here's the problem confused me:
The result of GGX term is 868.58123. It's a really large number that makes the final color way more bigger than 1. All another terms in BRDF are smaller than 1. If the incident light is just 1, this large reflected energy seems does not comply with the law of conservation of energy. I thought the reflected energy was definitely smaller than the incident.
I know there must be something wrong with my understanding. Thank you for your guidance.
Upvotes: 2
Views: 654
Reputation: 12458
The Khronos glTF Sample Viewer might be able to serve as an additional reference here.
It looks like you've implemented the D()
term, which the Sample Viewer implements on lines 41 - 46 of the BRDF shader.
But that's not the full specular term. That function is called further down, as part of function BRDF_specularGGX on lines 108 - 115. The result you have is mixed with several other terms before being used as the specular value.
There's some further reading of this in the glTF specification, section B.3.
Upvotes: 0