# GGX BRDF is greater than 1?

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

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 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.

• 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/…
– Tare
Mar 7, 2019 at 7:44
• You are confusing brdf with probabilities. gamedev.stackexchange.com/questions/62438/… gamedev.net/forums/topic/257668-brdf-range----greater-than-01- Mar 7, 2019 at 10:59
• 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$. Mar 7, 2019 at 12:30
• 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? Mar 7, 2019 at 15:07