我正在渲染旧游戏中的一些旧几何体。他们的客户有一些算法可以让他们看到附近有哪些区域,但我没有这种能力,所以我正在考虑剔除不必要的多边形。目前,我正在渲染整个区域中的每个多边形,无论我是否能看到它,无论它是否在可视范围内。显然,这是完全没有效率的。
我应该考虑使用哪种类型的剔除?
我知道我可以剔除不在平截头体中的多边形,这将有助于减轻一些负载,但我可以说,选择不渲染距相机一定距离的多边形吗?这个叫什么?我也在一些地区使用雾。同样的问题。我能否想出一种方法来剔除雾后面的所有东西,我看不到的区域。
有两件不同的事情需要考虑:您是否只想正确查看它,即隐藏的表面移除?然后简单的深度测试就可以完成工作;开销是,您处理的几何图形根本不会出现在屏幕上。但是,如果这是一款(非常)古老的游戏,您从中获取数据,很可能一张包含所有 Assets 的完整 map 的多边形比现代游戏中全屏可见的多边形要少。在这种情况下,您不会遇到任何性能问题。
如果您真的遇到性能问题,您需要在您想要花费多少时间、确定什么(不)可见以及实际渲染它方面找到一个平衡点。 10 年前,几乎像素完美以尽可能节省光栅化时间仍然至关重要。现代 GPU 拥有如此多的备用电源,只需对要包含在渲染中的内容进行粗略选择就足够了。
然而,这些计算完全超出了 OpenGL 或任何其他 3D 光栅化 API(例如 Direct3D)的范围——它们的任务只是使用复杂的光栅化方法在屏幕上绘制三角形;没有对象管理,没有更高级别的功能。因此,由您来实现。
典型的方法是使用空间分割结构。最流行的是 Kd 树、八叉树 和BSP 树。 BSP 树在空间上非常有效,但计算量更大。我个人更喜欢 Kd 树和八叉树的混合/组合,因为它们很容易修改以跟随场景中的动态变化。 BSP 树更新起来要困难得多(通常需要完全重新计算)。
鉴于这样的空间结构,很容易确定一个点是否位于特定的感兴趣区域。通过几何约束来选择树中的节点也非常简单,例如平面。这使得实现粗截头体剔除变得非常容易:使用截头体裁剪平面从平面内的树中选择所有节点。为了让 GPU 的工作更轻松,您可能需要对节点从近到远进行排序;树结构再次帮助您,因为您可以递归地对树进行排序,从而导致接近最佳的 O(n log(n)) 复杂度。
如果您仍然需要提高渲染性能,您可以使用树定义的空间划分,在递归到由测试范围。