C# 手写视锥体剔除:从裁剪空间矩阵推导到实战

📅 2026/8/27 10:35:30
C# 手写视锥体剔除:从裁剪空间矩阵推导到实战
开场场景一:移动端开放世界项目,DrawCall 已经飙到 800,Profiler 显示 GPU 在等顶点提交,但 CPU 这边还在把整个地图的网格塞进渲染队列——其中一大半根本不在镜头里。场景二:子弹击中判定,明明怪物在墙后,却莫名其妙扣了血。翻开代码一看,检测脚本只做了距离判断,完全没考虑摄像机朝向——怪物明明在视锥外,居然还在参与判定。这两个翻车的根源,都指向同一个缺失的能力:高效、精确的视锥体判定。Unity 自带的GeometryUtility.CalculateFrustumPlanes够用,但当你想做自定义 LOD、动态加载、服务器端回放判定,或者想在 Job System 里批量剔除时,就得手写一个可复用的视锥体模块。下面从裁剪空间的矩阵推导,一路撸到生产可用的 C# 代码。一、视锥体与裁剪空间的核心概念1.1 裁剪空间:为什么是 -w ≤ x ≤ w透视投影之后、透视除法之前,顶点处在齐次裁剪空间。在这个空间里,GPU 用一组非常整齐的不等式判断可见性——可见区域被六个平面框住:-w ≤ x ≤ w -w ≤ y ≤ w 0 ≤ z ≤ w // D3D / Vulkan / Metal 风格 // OpenGL 传统风格是 -w ≤ z ≤ w这就是透视除法xyz /= w之后,所有可见顶点的 x、y、z 都落在[-1, 1](z 在 D3D 风格下是[0, 1])的原