I'm taking an intro to computer graphics course, so this is something we haven't touched on.

I am reading this tutorial http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-16-shadow-mapping/ but I cant figure out what to do after creating the depth texture. The depth texture is from the lights point of view (directional light). I sent the depth texture to my post process shader where I want to apply the shadows. The depth texture: enter image description here

From what I understand from the article, I also need the position texture from the light's point of view.

The position texture:


And then the article determines if the current pixel is visible from the lights point of view like this:

float visibility = 1.0;
//ShadowCoord is the position of the vertex as seen from the light
if ( texture2D( shadowMap, ShadowCoord.xy ).z  <  ShadowCoord.z){
   visibility = 0.5;

Here is what I end up with: http://i.imgur.com/WpR9wHT.png

Im not sure, but I believe my position texture is wrong?

Edit: Here is how I create the position relative to the light texture in my shader:

positionSunPOV = (biasMatrix * sunMVP * vPosition).xyz;
// biasMatrix is the matrix that changes the coords from [-1,1] to [0,1]
// sunMVP is the model view projection matrix for the sun than I passed in
// vPosition is the position of the vertex

Here is how I create sunMVP:

SunDir = vec3(0,30,-30);
sunProjectionMatrix = ortho(left, right, bottom, ytop, nearO, farO);
sunViewMatrix = lookAt(SunDir, vec3(0,0,0), up);
sunModelMatrix = mat4(1.0);
//sunMV = mult(sunViewMatrix,sunModelMatrix); 
sunMVP = mult( sunProjectionMatrix, mult(sunViewMatrix,sunModelMatrix) ); 

1 Answer 1


First, from the picture it seems that in fact your light is not a "directional" light but a spotlight because you are using perspective projection, not an orthographic one (If not, then it is just the picture :) ). It is just a little thing, it should work more-or less the same.

The important thing is, you don't render the positions from the light's point of view. From the light's point of view, you have the shadow map.
You retrieve the position from the world position of the pixel (so you have to keep a texture of world positions, or retrieve the position from the main camera's depth buffer), then transform it by the light's viewProjection matrix (sunMVP in your code) in the fragment shader, then by taking the .z value of that transformed position and dividing it by .w, you get the real Depth of that pixel from the light's point of view, I call it the realDistance. The value which you sample from your shadow map will be the occluderDistance. If occluderDistance is less than realDistance, then it is occluded.

So in the pixel shader you have to do something like this:

float4 worldPosition = texture2D(WorldPosTexture,tex.xy);
//you can also retrieve world space position from depth buffer, but that's out of scope here.
float4 positionFromLight = worldPosition * sunMVP;
float realDistance = positionFromLight.z/positionFromLight.w;

if(realDistance > texture2D( shadowMap, ShadowCoord.xy ).z)

You might need to switch to realDistance < texture2D( shadowMap, ShadowCoord.xy ).z, it depends on what your depth buffer looks like. It can be 0.0-1.0 (close-far), or 1.0-0.0 (close-far).

Sidenote: A world position texture should look something like this: enter image description here


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .