遮挡剔除的主流方案
引言可见性问题作为计算机图形学的一个基本问题,它的主要目的是对给定的场景和观察视点,通过对遮挡关系进行快速判断,扔弃大量不需要绘制的图形对象,降低场景的复杂度,增加场景的真实感和流畅度,最终实现低负荷绘制和网络传输。
尤其是城市场景作为典型的稠密型场景,在任何一个视点均只能看到城市的冰山一角。其它如室内场景,墙壁遮挡了大部分场景,实际上从房屋的任何视点,仅能看到该屋内的场景及通过门廊的可见物。常用的一些方法有视域剔除,背面剔除,遮挡剔除,对大规模稠密场景,用得最多的方法是遮挡剔除。
遮挡剔除技术伴随计算机图形学的发展而发展,在早期的 3D 游戏中,传统的遮挡剔除就开始被应用在图形渲染中,优化图形产品的渲染性能。到今天,遮挡剔除已经发展了多个不同的方法,接下来将要介绍当今遮挡剔除的一些主流方案。
1、预计算遮挡剔除-保守简明的离线剔除方案
Airey针对建筑物内部稠密遮挡场景,最早提出了采用潜在可见集PVS(Potentially Visible Sets)解决消隐问题。该方法首先将场景分解成单元格,然后为这些单元格形成邻接图,并为每个单元建立一个PVS,之后绘制仅与PVS相关联的几何对象,并采用标准的z-buffer完成准确的消隐(如下图所示)。
预计算遮挡剔除:保守简明的离线剔除方案,先划分场景成一个个网格,再进行光线投射去计算网格可见性,得到潜在可见集Potential Visible Set, PVS),在运行时只需要花费查找表的时间即可得到可见信息。由于该方案运行时极低的消耗。在Unreal 4引擎中,预计算遮挡剔除系统的名字是Precomputed Visibility System
在接下来的一篇文章我将继续分析和探讨UE4中的可见性和遮挡剔除的功能进行试验并对他们的剔除效率进行分析对比-
2、利用深度缓存的剔除:较流行的在线剔除方案
2.1、硬件遮挡查询(Occlusion Query)
硬件遮挡查询(Occlusion Query)-在UE4默认开启的,它的基本原理如下流程图:
硬件遮挡查询(Occlusion Query)主要的问题在于它需要把查询到的结果从虚拟内存VRAM会读到系统内存System RAM,这样就会产生一个等待时间。因此为了决解这个问题,cpu会回读上一帧查询到的结果。包括在UE4中的硬件遮挡查询(Occlusion Query)也是回读上一帧查询到的结果。
2.2、层级深度缓冲(Hierarchical Z Buffer)
在了解Hierarchical Z Buffer之前,我们有必要先了解一下Z-buffer算法,他是经典的消除隐藏面的HSR算法(HSR-Hidden Surface Removel),他的基本原理如下:Z缓冲器算法也叫深度缓冲器算法,属于图像空间消隐算法该算法有帧缓冲器和深度缓冲器。对应两个数组:intensity(x,y)——属性数组(帧缓冲器)存储图像空间每个可见像素的光强或颜色depth(x,y)——深度数组(z-buffer)存放图像空间每个可见像素的z坐标。z-buffer他是在像素级上以近物取代远物(例如给定屏幕上一点(x,y),发射平行与z轴的射线,与物体R相交与p1、p2两点,z-buffer算法比较p1和p 2的z值, 将最大的z值存入z缓冲器中显然,p1在p 2前面,屏幕上(x,y) 这一点将显示p1点的颜色)。
z-buffer
层级深度缓冲(Hierarchical Z Buffer) 主要利用三个特性:object-space coherence、Image-space coherence、temporal coherence。提出了一个可见性算法,利用所有这三种类型的一致性(物体空间的连贯性、图像空间连贯性、时间连贯性),有时达到数量级的加速度相比传统的技术
(1)object-space coherence:
如果多边形的像素没有比 Z 缓冲区中已有的 Z 值更靠近观察者,我们会说多边形相对于 Z 缓冲区是隐藏的。
类似地,如果立方体的所有面都是隐藏的多边形,我们会说立方体相对于 Z 缓冲区是隐藏的。
最后,如果八叉树的关联立方体是隐藏的,我们将称其为隐藏节点。
通过这些定义,它可以将 Z -buffer与八叉树空间细分相结合:如果一个立方体相对于 Z 缓冲区是隐藏的,那么完全包含在立方体中的所有多边形也被隐藏。
(2)Image-space coherence
object-space octree 以扫描转换八叉树立方体的面为代价来剔除模型的大部分,立方体会占据图像中的大量像素,这种扫描转换可能非常昂贵。Image-space z pyramid无需逐个像素地检查多边形。Hi-Z意味着我们可以从最粗粒度的Z-Buffer开始进行遮挡查询和剔除,这样的查询效率更高。
Z pyramid 的基本思想是使用原始 Z-buffer作为金字塔中的最细层,然后通过选择距观察者最远的 Z,将每一层的四个 Z 值组合成下一个较粗层的一个 Z 值。 在金字塔的最粗层有一个 Z 值,它是整个图像中离观察者最远的 Z。
(3)temporal coherence
该算法同时维护一张时间连贯性表,表中存放每次消隐结束后可见的景物八叉树结点。这样当进行下一帧的消隐时,首先渲染这张表中的场景结点,然后提取此时的Z-Buffer 信息初始化图象包围盒树。新的一帧生成时,使用图象包围盒树检查时间连贯性表的每一项对应景物八叉树结点是否依然可见。如果不可见,从表中删除,如果可见,则继续保存。
2.3、Software Rasterization遮挡剔除
这个方案最早是Frostbite提出来,首先利用CPU构造一个低分辨率的Z-Buffer,在Z-Buffer上绘制一些场景中较大的遮挡体(美术设定的一些大物体+地形),在构造好的Z-Buffer上,绘制小物体的包围盒,然后执行类似于occlusion query的操作,查询当前物体是否被遮挡。
优点:纯CPU,不会有GPU stall;缺点:美术指定一些大的遮挡体,对于CPU bound的可能会负优化。
3、GPU Driven Rendering Pipeline
GPU Driven Rendering Pipeline作为一个比较特殊的存在,它不是一个具体的算法而是一种思路,这种思路代理了某些传统硬件上我们认为是固定管线的功能。
http://advances.realtimerendering.com/s2015/aaltonenhaar_siggraph2015_combined_final_footer_220dpi.pdf
以上就是我个人对遮挡剔除主流框架的一些概述,接下来我将会单独对Unreal Enigine4里面的可见性和遮挡剔除系统里面所有的功能进行试验,进一步探究他们遮挡剔除的性能并进行对比。
参考
[*]^大规模场景的消隐技术-王章野
[*]^大规模复杂场景的可见性问题研究-普建涛
[*]^Towards Image Realism with Interactive Update Rates-Airey 1990
[*]^https://www.cnblogs.com/cnblog-wuran/p/9830994.html
[*]^Hierarchical Z-Buffer Visibility
[*]^https://zhuanlan.zhihu.com/p/66407205
页:
[1]