I am implementing a GGX BRDF, this is the formula I used is from:https://schuttejoe.github.io/post/ggximportancesamplingpart1/ enter image description here

enter image description here

And this is my implementation:

float BRDF(float3 viewDir, float roughness, float3 normal, float3 Li) {
            float3 halfDir = normalize(Li + viewDir);
            float nl = saturate(dot(normal, Li));
            float nh = saturate(dot(normal, halfDir));

            half lv = saturate(dot(Li, viewDir));
            half lh = saturate(dot(Li, halfDir));
            half nv = abs(dot(normal, viewDir));

            float a2 = roughness * roughness;
            float G2 = SmithGGXMaskingShadowing(nl, nv, a2);

            float D = GGX(nh, roughness);
            return G2 * D /(4 * abs(nv) * abs(nl));

float SmithGGXMaskingShadowing(float NdotL, float NdotV, float a2)

            float denomA = NdotV * sqrt(a2 + (1.0f - a2) * NdotL * NdotL);
            float denomB = NdotL * sqrt(a2 + (1.0f - a2) * NdotV * NdotV);

            return 2.0f * NdotL * NdotV / (denomA + denomB);

float GGX(float NdotH, float a) {
            float a2 = sqr(a);
            return a2 / (UNITY_PI * sqr(sqr(NdotH) * (a2 - 1) + 1));

I assume the fresnel term is constant: 1. However, I found that my BRDF sometimes give me number greater than 1.

  • $\begingroup$ Shouldn't the return value be a float3? Also, why do you assume fresnel to be constant 1? That would only be true for an incident angle of $90°$. Have a look at Natty Hoffman's Siggraph Physically Based Shading Course, he displays some Fresnel values plotted for different angles (p. 15) blog.selfshadow.com/publications/s2013-shading-course/hoffman/… $\endgroup$
    – Tare
    Mar 7, 2019 at 7:44
  • 1
    $\begingroup$ You are confusing brdf with probabilities. gamedev.stackexchange.com/questions/62438/… gamedev.net/forums/topic/257668-brdf-range----greater-than-01- $\endgroup$ Mar 7, 2019 at 10:59
  • 1
    $\begingroup$ A brdf can be larger than $1$ and be energy conserving. Consider the ideal specular reflection/refraction brdf which can be considered to go to infinity at a single point. It's the integral of the brdf multiplied by the cosine for all directions that needs to be $\leq 1$. $\endgroup$
    – lightxbulb
    Mar 7, 2019 at 12:30
  • $\begingroup$ Thank you very much. I understand now. If I do importance sampling on brdf, then my brdf/pdf can rescale my value back to [0,1] right? But if I do importance sampling on the light source, my brdf/pdf can still has some value greater than 1 because the pdf is the pdf of sampling my light source, not the pdf of sampling brdf. Am I correct? $\endgroup$ Mar 7, 2019 at 15:07


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.