I am trying to use directional light. My shader is essentially the same as the one from the lighthouse tutorial
http://www.lighthouse3d.com/opengl/glsl/index.php?dirlightpix
But it produces some artifacts at certain angles.
Namely I get a black streak. This shouldn’t happen at all, as it should be lit as the ambient light colour, like the rest of the back of the model.
The left shows the problem, the right shows the model rotated slightly, which makes the problem disappear.
My shader is this
char *vertexShaderColour =
"varying vec4 diffuse,ambient;
"
"varying vec3 normal,lightDir,halfVector;
"
"void main()
"
"{
"
/* first transform the normal into eye space and normalize the result */
"normal = normalize(gl_NormalMatrix * gl_Normal);
"
/* now normalize the light's direction. Note that according to the
OpenGL specification, the light is stored in eye space. Also since
we're talking about a directional light, the position field is actually
direction */
"lightDir = normalize(vec3(gl_LightSource[0].position));
"
/* Normalize the halfVector to pass it to the fragment shader */
"halfVector = normalize(gl_LightSource[0].halfVector.xyz);
"
/* Compute the diffuse, ambient and globalAmbient terms */
"diffuse = gl_FrontMaterial.diffuse * gl_LightSource[0].diffuse;
"
"ambient = gl_FrontMaterial.ambient * gl_LightSource[0].ambient;
"
"ambient += gl_LightModel.ambient * gl_FrontMaterial.ambient;
"
"gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
"
"gl_FrontColor = gl_Color;
"
"}
";
char *fragmentShaderColour =
"varying vec4 diffuse,ambient;
"
"varying vec3 normal,lightDir,halfVector;
"
"void main()
"
"{
"
"vec3 n,halfV,viewV,ldir;
"
"float NdotL,NdotHV;
"
"vec4 color = ambient;
"
/* a fragment shader can't write a verying variable, hence we need
a new variable to store the normalized interpolated normal */
"n = normalize(normal);
"
/* compute the dot product between normal and ldir */
"NdotL = max(dot(n,lightDir),0.0);
"
"if (NdotL > 0.1) {
"
"halfV = normalize(halfVector);
"
"NdotHV = max(dot(n,halfV),0.0);
"
"color += gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(NdotHV,gl_FrontMaterial.shininess);
"
"color += diffuse * NdotL;
"
"}
"
"color *= gl_Color;
"
//
// test
//
"color.rgb = pow(vec3(color), vec3(1.0 / 4.2));"
"gl_FragColor = color;
"
"}
";
I ramped up the brightness at the end to make the problem more obvious.