# Cook Torrance model implementation : black specular light

I am trying to implement the Cook-Torrance model, and this is how I calculate the parameter Rs:

``````float Rs(float m,float F,vec3 N, vec3 L,vec3 V, vec3 H)
{
float result;
float NdotV= dot(N,V);
float NdotH= dot(N,H);
float NdotL= dot(N,L);
float VdotH= dot(V,H);
float Geom= min(min(1.0, (2.0*NdotV*NdotH)/VdotH), (2.0*NdotL*NdotH)/VdotH);
float Rough= pow(1.0/(pow(m,2.0)*pow(NdotH,4.0)), ( pow(NdotH,2.0)-1.0)/( pow(m,2.0)*pow(NdotH,2.0)));
float Fresnel= F + pow(1.0-VdotH,5.0) * (1.0-F);
return (Fresnel * Rough * Geom)/(NdotV*NdotL);
}
``````

I apply this formula:

Where I set m to 0.5 and F0 to 2.0.

But I think it's wrong because I'm getting a black area where there should be the specular light:

PS: With OpenGL 2.1, GLSL 1.20.

-

``````float Rough= pow(1.0/(pow(m,2.0)*pow(NdotH,4.0)), ( pow(NdotH,2.0)-1.0)/( pow(m,2.0)*pow(NdotH,2.0)));
``````

Does not correctly reflect the formula for the `Roguhness` term. It should be something like:

``````float Rough= (1.0/(pow(m,2.0)*pow(NdotH,4.0)) * exp ( pow(NdotH,2.0)-1.0)/( pow(m,2.0)*pow(NdotH,2.0)));
``````

that is, exp usually stands for `e` raised to the power `x` (e is the Euler number, the natural logarithm base, etc.)

-
Ok I thought it was solved, but it still doesn't work. Or better: it works only if F isn't greater than 1.0 ; Otherwise I see all the reflected light as black. – Ramy Al Zuhouri Feb 5 '13 at 17:51
Perhaps you should do some debugging and chop down some terms till you find which one is corrupted - it could be that you send improper uniforms or varyings. For example, try to eliminate the roughness, fresnel and geometric factors one by one and see which one destroys the results. Then work on that one. Anyway, this is highly unoptimized shader code and I believe there are ways of making it faster. Could you do some reverse engineering and analyse the code from this site as well? madman07.ugu.pl/index.php?show=007_cont#wrapper – teodron Feb 6 '13 at 8:44
Fresnel is the term that makes this happen, if F is greater than 1.0 ,because Rough and Geom don't depend on F. – Ramy Al Zuhouri Feb 6 '13 at 12:42
Well, now I see the problem. F0 is supposed to be between 0 and 1.0 in the first place. It must have something to do with how the view/eye vector and the half vector alignment contribute to the fresnel reflectivity, therefore it is a linear interpolation factor. Mind it and keep it in [0,1]. – teodron Feb 6 '13 at 14:53
I think that the c++ code was wrong, if I switch to another project I don't have this problem. – Ramy Al Zuhouri Feb 7 '13 at 20:30