Sign in to follow this  
gzaloprgm

Z Fighting in specular component (GLSL directional light)

Recommended Posts

Hi, I am experiencing Z-fighting in the specular component of my GLSL computed directional light. This is mostly noticed in surfaces perpendicular to the light direction. This are my shaders: Vertex Shader: uniform vec3 lightDir; uniform mat4 viewMatrixInverse; varying vec3 eyeNormal,eyeLDir,eyeVector; void main(void) { gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex; gl_Position = ftransform(); gl_TexCoord[0] = gl_MultiTexCoord0; gl_FrontColor = gl_Color; eyeNormal = gl_NormalMatrix * gl_Normal; eyeLDir = mat3(viewMatrixInverse) * normalize(lightDir); eyeVector = vec3(gl_ModelViewMatrix * gl_Vertex); } Fragment Shader: uniform sampler2D colorMap; const vec4 LA = vec4(0.3, 0.3, 0.3, 1.0); const vec4 LD = vec4(0.5, 0.5, 0.5, 1.0); const vec4 LI = vec4(0.5, 0.5, 0.5, 1.0); const float LIi = 32.0; varying vec3 eyeNormal,eyeLDir,eyeVector; vec3 directionalLight(vec3 eNorm, vec3 eLDir, vec3 eVector){ float LSt, LSi; vec3 result, reflejo; float LDi = max(dot(normalize(eNorm), normalize(eLDir)),0.0); result = vec3(0,0,0); if(LDi > 0.0){ result += LDi * LD; reflejo = reflect(normalize(eLDir), normalize(eNorm)); LSt = max(dot(normalize(eVector), normalize(reflejo)),0.0); LSi = pow(LSt, LIi); result += LI * LSi; } return result; } void main (void) { vec4 result = LA; vec4 texel = texture2D(colorMap,gl_TexCoord[0].st); result += vec4(directionalLight(eyeNormal,eyeLDir,eyeVector),1.0); gl_FragColor = result*texel; } In this image the light direction is down, I am looking at a vertical wall and there is some surface acne. Is there anything I am not calculating correctly in my shader? Thanks for your help, Gzaloprgm

Share this post


Link to post
Share on other sites
I suppose that you dont't have 2 coplanar polygons in your wall. So that can't be really z-fighting. Still I think it has been caused by the same problem: the floating point imprecision. When the computations involve floating point numbers one should write:

if(abs(LDi) > EPSILON)
{
/* do stuff */
}

instead of this:

if(LDi > 0.0)
{
/* do stuff */
}

where EPSILON is some small number (ex. 0.001). This will take care of the rounding errors including the occasional change of sign.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this