Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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:

enter image description here

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:

enter image description here

PS: With OpenGL 2.1, GLSL 1.20.

share|improve this question
up vote 2 down vote accepted
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.)

share|improve this answer
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? – 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

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.