Hello everyone.
I am trying to implement a Shadow Map from a directional light source in my (LWJGL-) Open GL program.
I did base my implementation on the concepts from
http://fabiensanglard.net/shadowmapping/index.php.They are still not behaving as the should however.
I have attached a few pictures in hope someone can help me find the issue in the code.
I render the scene from the lightsource into a framebuffer first with a texture attached to the depth attachment point. Rendering the shadow map works like this.
cam.storePosition(); //store where user has put you
cam.setPosition(suns.get(0)); //move camera to light source
cam.turnCameraTowards(0f, 0f, 0f); //light source is oriented into center of scene
cam.applyModelviewMatrix(); //update Modelview with camera's new values
glEnable(GL_CULL_FACE);
glCullFace(GL_FRONT); //render only the backsides
glBindTexture(GL_TEXTURE_2D, 0); // unlink potential texture that was used before
glBindFramebuffer(GL_FRAMEBUFFER,shadow_framebufferID); //prepare to store shadow
glColorMask(false, false, false, false); //no need for color
renderModelsQuick(); //do a quick render for the models, does not use a shader
//save bias*projection*modelview in gl_TextureMatrix[1]
glMatrixMode(GL_TEXTURE);
glActiveTextureARB(GL_TEXTURE1_ARB);
//get necessary matrices
FloatBuffer m = BufferUtils.createFloatBuffer(16);
FloatBuffer p = BufferUtils.createFloatBuffer(16);
FloatBuffer b = BufferUtils.createFloatBuffer(16);
glGetFloat(GL_MODELVIEW_MATRIX, m);
glGetFloat(GL_PROJECTION_MATRIX, p);
b.put(new float[]{ //create the bias
0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 0.5f, 0.0f,
0.5f, 0.5f, 0.5f, 1.0f});
b.flip();
//make the multiplications
glLoadMatrix(b);
glMultMatrix(p);
glMultMatrix(m);
//matrix is now stored in gl_TextureMatrix[1]
glMatrixMode(GL_MODELVIEW);//reset mode
glActiveTextureARB(GL_TEXTURE0_ARB);//reset active texture unit
glBindFramebuffer(GL_FRAMEBUFFER,0); //reset to normal frame
glColorMask(true, true, true, true); //turn color back on
glDisable(GL_CULL_FACE); //render only the backsides
cam.restorePosition(); //reset camera perspective
cam.applyModelviewMatrix(); //reset the modelview matrix to old position
The full rendering loop then uses
glUseProgram(shadowShader);
glBindTexture(GL_TEXTURE_2D,shadow_depthTextureBufferID);
//rendering the scene again...
with the vertex shader being
varying vec4 shadowCoordinate;
varying vec3 vertex;
varying vec3 normal;
void main()
{
shadowCoordinate = gl_TextureMatrix[1] * gl_Vertex; //coordinate in lightCoordinates
vertex = vec3(gl_ModelViewMatrix * gl_Vertex); //coordinate in cameraCoordinates
normal = normalize(gl_NormalMatrix * gl_Normal); //normalize in case normal is not normal
gl_Position = ftransform(); //which is gl_ModelViewProjectionMatrix * gl_Vertex;
}
and the fragment shader
varying vec4 shadowCoordinate;
uniform sampler2D shadowMap;
varying vec3 vertex;
varying vec3 normal;
void main(){
vec4 shadowCoordinateWdivide = shadowCoordinate / shadowCoordinate.w ;
// Used to lower moire pattern and self-shadowing
//shadowCoordinate.z += 0.0005;
float distanceFromLight = texture2D(shadowMap,shadowCoordinate.st).z;
float shadow = 1.0;
if (shadowCoordinate.w > 0.0)
shadow = distanceFromLight < shadowCoordinateWdivide.z ? 0.5 : 1.0 ;
//calculate phong shading
vec3 lightvector = normalize(gl_LightSource[0].position.xyz - vec3(vertex));
vec3 eyevector = normalize(-vec3(vertex)); // we are in Eye Coordinates, so EyePos is (0,0,0)
vec3 reflectionvector = normalize(-reflect(lightvector,normal));
//calculate Ambient Term:
vec4 ambient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient;
//calculate Diffuse Term:
vec4 diffuse = gl_LightSource[0].diffuse * max(dot(normal, lightvector), 0.0) * gl_FrontMaterial.diffuse;
// calculate Specular Term:
vec4 specular = gl_LightSource[0].specular * pow(max(dot(reflectionvector, eyevector), 0.0), gl_FrontMaterial.shininess) * gl_FrontMaterial.specular;
// write Total Color, modify with shadow value:
gl_FragColor = shadow*clamp(vec4(gl_FrontLightModelProduct.sceneColor + ambient + diffuse + specular), 0.0, 1.0);
}
As you can see on the attached pictures, rendering the shadow map seems to be correct, since visualizing the depth buffer shows the scene correctly from the lightsource's perspective. Since the shadows are off, I suspect an error in the shader but after 3 days of work, I am getting kind of blind. I mean, I have two ****ing books here and the idea is primitive, still this bug eludes me...
Somebody here who is able to help me?
The light source has been visualized by a sphere. This sphere is rendered after rendering the scene and applying shadows, so it is not interfiering. It is oriented towards (0,0,0) which is between the two pillars.
EDIT: post if you want to see more specific lines of code but for god's sake post and help me, I am really angry at my engine at the moment