• ### Popular Now

• 12
• 10
• 10
• 13
• 10

This topic is 1700 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi,
I've been messing around with a basic shadow map implementation, and trying out approaches to dealing with the various artifacts.  While reading this Direct3D article on MSDN: Common Techniques to Improve Shadow Depth Maps, there is a section 'Moving the Light in Texel-Sized Increments' which seemed to have a simple solution that I could use, but I must be missing something in my implementation because I can't get rid of the shimmering...

The concept of quantizing the movement of the light frustum makes sense:

vLightCameraOrthographicMin /= vWorldUnitsPerTexel;
vLightCameraOrthographicMin = XMVectorFloor(vLightCameraOrthographicMin);
vLightCameraOrthographicMin *= vWorldUnitsPerTexel;
vLightCameraOrthographicMax /= vWorldUnitsPerTexel;
vLightCameraOrthographicMax = XMVectorFloor(vLightCameraOrthographicMax);
vLightCameraOrthographicMax *= vWorldUnitsPerTexel;

but the article glosses over a few details that leave me puzzled.  In particular the statement "The vWorldUnitsPerTexel value is calculated by taking a bound of the view frustum, and dividing by the buffer size." and the following bit of code:

FLOAT fWorldUnitsPerTexel = fCascadeBound / (float)m_CopyOfCascadeConfig.m_iBufferSize;
vWorldUnitsPerTexel = XMVectorSet(fWorldUnitsPerTexel, fWorldUnitsPerTexel, 0.0f, 0.0f);

I don't understand how to get the fCascadeBound value, and I assume the divisor in the expression is the shadow map resolution?  Also, the vLightCameraOrthographicMin and Max values are in light view space, is that correct?

Thanks,

##### Share on other sites

After a lot of trial and error I was able to get it to work.  Since my light frustum dimensions are fixed, I convert the center point into texel space, floor the X and Y coordinates, then convert it back to world space:

// (sceneBounds.Center has been placed based on the camera frustum.)

float texelsPerWorldUnit = (float)SMAP_SIZE / (sceneBounds.Radius * 2.0f);

Matrix lightViewAtOrigin = Matrix.CreateScale(texelsPerWorldUnit) *
Matrix.CreateLookAt(Vector3.Zero, -sceneLights[0].Direction, Vector3.Up);

Matrix lightViewAtOriginInv = Matrix.Invert(lightViewAtOrigin);

sceneBounds.Center = Vector3.Transform(sceneBounds.Center, lightViewAtOrigin);
sceneBounds.Center.X = (float)(Math.Floor(sceneBounds.Center.X));
sceneBounds.Center.Y = (float)(Math.Floor(sceneBounds.Center.Y));
sceneBounds.Center = Vector3.Transform(sceneBounds.Center, lightViewAtOriginInv);

lightView = Matrix.CreateLookAt(sceneBounds.Center - sceneLights[0].Direction *
sceneBounds.Radius * 2.0f, 0.0f, sceneBounds.Radius * 6.0f);