void ComputeFrustum(float minZ, float maxZ, RenderView cameraRenderView, int split) { // Shorten the view frustum according to the shadow view distance Matrix cameraMatrix = cameraRenderView.GetWorldMatrix(); Vector4 camPos = cameraRenderView.GetEyePosShader(); for (int i = 0; i < 4; i++) splitFrustumCornersVS[i] = frustumCornersVS[i + 4] * (minZ / camPos.W); for (int i = 4; i < 8; i++) splitFrustumCornersVS[i] = frustumCornersVS[i] * (maxZ / camPos.W); Vector3.Transform(splitFrustumCornersVS, ref cameraMatrix, frustumCornersWS); // Position the shadow-caster camera so that it's looking at the centroid, // and backed up in the direction of the sunlight BoundingBox sceneBounds = scene.GetSceneDimensions(); Vector3 sceneCenter = (sceneBounds.Min + sceneBounds.Max) * 0.5f; Vector3 sceneExtents = (sceneBounds.Max - sceneBounds.Min) * 0.5f; Vector3 lightDir = -this.Transformation.GetPosition(); lightDir.Normalize(); Matrix viewMatrix = Matrix.CreateLookAt(sceneCenter - (lightDir * sceneExtents.Length()), sceneCenter, new Vector3(0, 1, 0)); // Determine the position of the frustum corners in light space Vector3.Transform(frustumCornersWS, ref viewMatrix, frustumCornersLS); // Calculate an orthographic projection by sizing a bounding box // to the frustum coordinates in light space Vector3 mins = frustumCornersLS[0]; Vector3 maxes = frustumCornersLS[0]; for (int i = 0; i < 8; i++) { maxes = Vector3.Max(frustumCornersLS[i], maxes); mins = Vector3.Min(frustumCornersLS[i], mins); } // Create an orthographic camera for use as a shadow caster //const float nearClipOffset = 380.0f; float nearPlane = -maxes.Z-sceneExtents.Length(); float farPlane = -mins.Z; renderViews[split].SetPosition(viewMatrix.Translation); renderViews[split].SetView(viewMatrix); renderViews[split].SetNearPlane(nearPlane); renderViews[split].SetFarPlane(farPlane); renderViews[split].SetProjection(Matrix.CreateOrthographicOffCenter(mins.X, maxes.X, mins.Y, maxes.Y, nearPlane, farPlane)); lightViewProjectionMatrices[split] = renderViews[split].GetViewProjection(); lightClipPositions[split] = renderViews[split].GetEyePosShader(); }