106 lines
3.8 KiB
C#
Raw Normal View History

2025-07-14 16:40:10 +08:00
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]);
}
}
}