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 '19 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 '19 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 '19 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 '19 at 15:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.