Ok I came back to this after working on more interesting parts of my game and although I've improved it by using a sphere based approach to making the projections it hasn't really improved the shimmering that much. In fact if i comment out my texel snapping part it makes little difference. I'm getting a bit stumped. Maybe I've been looking at it too long. It's acceptable now I guess but i'd like it to be totally rock solid ideally
This creates the projection and view for each cascade. Any ideas what i've missed?
public void GenerateCSMOrthoSliceTS(float pNearClip, float pfarClip)
{
Vector3[] frustumCorners = new Vector3[8];
Matrix mCameraViewProj = _Camera.CameraView;
mCameraViewProj *= Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, _Camera._aspectRatio, pNearClip, pfarClip);
BoundingFrustum oCameraViewProjFrustum = new BoundingFrustum(mCameraViewProj);
frustumCorners = oCameraViewProjFrustum.GetCorners();
Vector3 frustumCenter = new Vector3(0, 0, 0);
for (int i = 0; i < 8; i++)
frustumCenter += frustumCorners[i];
frustumCenter /= 8;
lightsView = Matrix.Identity;
lightsViewProjectionMatrix = Matrix.Identity;
float radius = (frustumCorners[0] - frustumCorners[6]).Length() / 2.0f;
float texelsPerUnit = (float)4096 / (radius * 2.0f);
Matrix mTexelScaling = Matrix.CreateScale(texelsPerUnit);
SunlightDirection.Normalize();
Vector3 baselookAt = new Vector3(SunlightDirection.X, SunlightDirection.Y, SunlightDirection.Z);
Matrix mLookAt = Matrix.CreateLookAt(Vector3.Zero, baselookAt, Vector3.Up);
mLookAt = Matrix.Multiply(mTexelScaling, mLookAt);
Matrix mLookAtInv = Matrix.Invert(mLookAt);
frustumCenter = Vector3.Transform(frustumCenter, mLookAt);
frustumCenter.X = (float)Math.Floor(frustumCenter.X); //clamp to texel increment
frustumCenter.Y = (float)Math.Floor(frustumCenter.Y); //clamp to texel increment
frustumCenter = Vector3.Transform(frustumCenter, mLookAtInv);
Vector3 eye = frustumCenter + (SunlightDirection * radius * 2.0f);
ShadowLightPos = eye;
Vector3 ShadowLookAt = frustumCenter;
ShadowLightView = Matrix.CreateLookAt(eye, ShadowLookAt, new Vector3(0, 1, 0));
ShadowLightProjection = Matrix.CreateOrthographicOffCenter(-radius, radius, -radius, radius, -radius * 8.0f, radius * 8.0f);
mCascadeProjection = ShadowLightProjection;
lightsView = ShadowLightView;
lightsViewProjectionMatrix = lightsView * ShadowLightProjection;
}