Stable Cascaded Shadow Maps - Sphere Based Bounding Help

Started by
11 comments, last by skyemaidstone 6 years, 7 months ago

Thanks for the answers. That's exactly what I'm trying now Joe, ie simplifying the problem.

If I can get rid of the jiggling for 1 CSM "slice" then I'm there really. Filtering and stuff works fine already.

I'll read some more and see if I can figure out how to make my slice ignore camera rotation. I've tried moving them to texel increments (based on one of the links above CSM which i've read and reread) but the problem isn't real;y improved. 

Increasing my shadow map size to something ridiculous didn't improve the jiggling either so it does seem to be the rotation causing the problem. Hence I was trying to use the sphere based approach for bounding sphere but i just don't "get it". 

Or maybe I'm just doing the "move bounding box in texel increments" incorrectly..  I shall persevere.

Advertisement

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;
        }

 

This topic is closed to new replies.

Advertisement