# Directional shadow mapping view/projection matrices

I've got shadow mapping with directional lights working, but I believe I am constructing the view/projection matrices wrong.

Here's how I build them:

Mat4 viewMatrix = LookAt(lighting.mCameraPosition + (directionalLight.mLightDirection * Z_FAR / 2.0f), -directionalLight.mLightDirection, Vec3(0.0f, 1.0f, 0.0f));
Mat4 lightVP = CreateOrthographicMatrix(-Z_FAR, Z_FAR, -Z_FAR, Z_FAR, Z_NEAR, Z_FAR) * viewMatrix;


The problem is the shadows become skewed and change depending on the camera position, which is bad. What is the proper way of doing this?

EDIT:

1) No, that is what I'm not sure about; currently as you said it is the camera position and thus the shadows moves around when I move the camera, which is bad - what should be the actual position, since directional lights have no position?

2) Also using Z_FAR DOES make it pixelated which is my second problem - but must not the boundaries be Z_FAR in all directions, otherwise objects in the view range may not cast shadows?

• I hope lighting.mCameraPosition is the position of your light source, otherwise the position of the directional light will change and it will lead to flickering when the camera is moving. Also, what is the value of z_far? If you make an ortho matrix with those ranges, it could easily result in some kind of precision issue. In fact if ortho matrix covers a large enough range, your entire scene might be contained in a couple of texels of the shadow map. – TravisG Jan 27 '14 at 0:57
• updated question – KaiserJohaan Jan 27 '14 at 18:47

You have two problems here:

First problem:

Adding some kind of position offset to your lookat matrix (currently your camera position) is essentially supposed to center the "light camera" (whatever your light source sees from its view) around that position. This is done because the shadow map will only cover a limited range, but if your shadow maps in one directions extends to 10 [whatever distance unit you have], but objects are positioned at 12[whatever distance unit you have], you obviously still want those objects to cast shadows. So you apply this position offset to all objects via the shadow caster view transform, so they're essentially "pushed into" the visible range of whatever the camera sees.

The reason this causes artifacts if done in a straight forward way is because due to how rasterization works, the amount of pixels that are rasterized for each object are not the same if you change positions of either the objects or of the visible range that the camera sees. The solution to this is to snap that position offset you apply to multiples of the shadow map texel size. I.e. the offset you apply must be a multiple of the shadow map texel size in each direction. You do this by just taking your normal offset, and snapping it to a multiple (either the nearest, or just floor/ceil, doesn't matter I think) of the texel size.

vec3 camPos = lighting.mCameraPosition;