namespace UnityEngine.Rendering.Universal { public class DebugCascadeShadow : MonoBehaviour { public Camera targetCamera; public bool showCullingSpheres = true; public bool showCameraFrustums = true; public Color[] cascadeColors = new Color[] { new Color(1, 0, 0, 0.5f), // 红 new Color(0, 1, 0, 0.5f), // 绿 new Color(0, 0.5f, 1, 0.5f), // 蓝 new Color(1, 1, 0, 0.5f) // 黄 }; public static Vector3 cascadeSplits; public static Vector4[] cullingSpheres= new Vector4[4]; void OnDrawGizmos() { if (targetCamera == null) return; // 可视化Culling Spheres if (showCullingSpheres) { for (int i = 0; i < cullingSpheres.Length; i++) { if (cullingSpheres[i].w <= 0) continue; Gizmos.color = cascadeColors[i % cascadeColors.Length]; Vector3 sphereCenter = cullingSpheres[i]; float sphereRadius = cullingSpheres[i].w; Gizmos.DrawWireSphere(sphereCenter, sphereRadius); } } // 可视化相机视锥体级联 if (showCameraFrustums) { float lastSplit = targetCamera.nearClipPlane; for (int i = 0; i < 3; i++) { if (cascadeSplits[i] <= 0) break; Gizmos.color = cascadeColors[i % cascadeColors.Length]; DrawCascadeFrustum(targetCamera, lastSplit, cascadeSplits[i]); lastSplit = cascadeSplits[i]; } } } private void DrawCascadeFrustum(Camera cam, float startDist, float endDist) { // 计算视锥体角点 Vector3[] nearCorners = GetFrustumCorners(cam, startDist); Vector3[] farCorners = GetFrustumCorners(cam, endDist); // 绘制视锥体线框 Gizmos.DrawLine(nearCorners[0], farCorners[0]); Gizmos.DrawLine(nearCorners[1], farCorners[1]); Gizmos.DrawLine(nearCorners[2], farCorners[2]); Gizmos.DrawLine(nearCorners[3], farCorners[3]); // 绘制近/远平面 DrawFrustumPlane(nearCorners); DrawFrustumPlane(farCorners); } private Vector3[] GetFrustumCorners(Camera cam, float distance) { Vector3[] corners = new Vector3[4]; Transform camTransform = cam.transform; float halfFOV = cam.fieldOfView * 0.5f * Mathf.Deg2Rad; float aspect = cam.aspect; float height = distance * Mathf.Tan(halfFOV); float width = height * aspect; // 计算相对于相机的角点 corners[0] = camTransform.forward * distance + camTransform.up * height - camTransform.right * width; // 左下 corners[1] = camTransform.forward * distance + camTransform.up * height + camTransform.right * width; // 右下 corners[2] = camTransform.forward * distance - camTransform.up * height + camTransform.right * width; // 右上 corners[3] = camTransform.forward * distance - camTransform.up * height - camTransform.right * width; // 左上 // 转换到世界坐标 for (int i = 0; i < 4; i++) { corners[i] = camTransform.position + corners[i]; } return corners; } private void DrawFrustumPlane(Vector3[] corners) { Gizmos.DrawLine(corners[0], corners[1]); Gizmos.DrawLine(corners[1], corners[2]); Gizmos.DrawLine(corners[2], corners[3]); Gizmos.DrawLine(corners[3], corners[0]); } } }