Author Topic: [FIXED]Shadow Mapping is off  (Read 2271 times)

0 Members and 1 Guest are viewing this topic.

Offline Vidmaster

  • 211
  • Inventor of FS2 bullettime ;-)
[FIXED]Shadow Mapping is off
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.
Code: [Select]
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

Code: [Select]
glUseProgram(shadowShader);
glBindTexture(GL_TEXTURE_2D,shadow_depthTextureBufferID);
//rendering the scene again...

with the vertex shader being

Code: [Select]

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

Code: [Select]
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?   :nervous:

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  :banghead:
« Last Edit: July 21, 2012, 08:15:38 am by Vidmaster »
Devoted member of the Official Karajorma Fan Club (Founded and Led by Mobius).

Does crazy Software Engineering for a living, until he finally musters the courage to start building games for real. Might never happen.

 

Offline Aardwolf

  • 211
  • Posts: 16,384
Re: Shadow Mapping is off
First you said it was a directional light source (which is how it looks in the picture where shadows seem to be working), but the way you draw it suggests it is a point light?

Is the point on the model where those artifacts are appearing within the valid range of texture coordinates (i.e. (s, t) somewhere between 0 and 1)? It looks like it isn't.

 

Offline Vidmaster

  • 211
  • Inventor of FS2 bullettime ;-)
Re: Shadow Mapping is off
It is a directional light source, the sphere is just a debug visualization.
Devoted member of the Official Karajorma Fan Club (Founded and Led by Mobius).

Does crazy Software Engineering for a living, until he finally musters the courage to start building games for real. Might never happen.

 

Offline Aardwolf

  • 211
  • Posts: 16,384
Re: Shadow Mapping is off
Ok then, I'ma continue with the "bad texcoords" hypothesis. Try modifying the fragment shader so that instead of doing what it's doing, it outputs shadowCoordinate.st. I'll bet that part with the stripes has s and/or t outside of the range [0, 1]

  

Offline Vidmaster

  • 211
  • Inventor of FS2 bullettime ;-)
Re: Shadow Mapping is off
shadowCoordinate.st was indeed the bug. I need to look up shadowCoordinateWDivide of course, stupid typo...
Devoted member of the Official Karajorma Fan Club (Founded and Led by Mobius).

Does crazy Software Engineering for a living, until he finally musters the courage to start building games for real. Might never happen.