106 lines
3.8 KiB
C#
106 lines
3.8 KiB
C#
|
|
|
||
|
|
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]);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|