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