示例#1
0
        private static FloatSphere GetShadowSphere(
            Float4x4 ndcToWorldMat,
            Float4x4 worldToLightMat,
            float shadowDistance)
        {
            //Frustum of the camera that will be covered by the shadow map in NDC space
            //Note: this covers the entire screen but only to a certain depth
            FloatBox shadowNDC = new FloatBox(
                min: (-1f, -1f, 0f),
                max: (1f, 1f, DepthUtils.LinearToDepth(
                          shadowDistance,
                          Camera.NEAR_CLIP_DISTANCE,
                          Camera.FAR_CLIP_DISTANCE)));

            //Gather points of the frustum
            Span <Float3> points = stackalloc Float3[8];

            shadowNDC.GetPoints(points);

            //Transform all the points to lightspace (ndc -> world -> lightspace)
            Float3 center = Float3.Zero;

            for (int i = 0; i < points.Length; i++)
            {
                points[i] = (worldToLightMat * ndcToWorldMat).TransformPoint(points[i]);
                center    = i == 0 ? points[i] : (center + points[i]);
            }
            center /= points.Length;

            //The the longest diagonal of the frustum and base our sphere on that
            float squareDiag1 = (points[0] - points[6]).SquareMagnitude;
            float squareDiag2 = (points[2] - points[4]).SquareMagnitude;
            float radius      = FloatUtils.SquareRoot(FloatUtils.Max(squareDiag1, squareDiag2)) * .5f;

            return(new FloatSphere(center, radius));
        }