背面剔除|无剔除模式与透明物体的绘制

假设你正在一个场景中观察一个不透明的球体,大约一半的球体是看不见的。从这个观察得出的结论是,不可见的东西不需要被渲染,因为它对最终图像没有贡献。因此,球体的背面不需要处理,这就是背面剔除的思想。这种类型的剔除也可以一次对整个物体组进行,因此被称为集群背面剔除。

假设相机在物体外面,并且没有与物体穿插,所有不透明物体背面的一部分三角形都可以从进一步处理中剔除。如果已知投影三角形在屏幕空间中是顺时针方向的,则逆时针方向的三角形(第16.3节)是背面的。这个测试可以通过计算二维屏幕空间中三角形的带符号的面积来实现,带负号的区域表示三角形应该被剔除,这可以在屏幕映射过程中实现。

另一种确定三角形是否面向背面的方法是创建一个从三角形所在平面上的任意点(最简单的方法是选择其中一个顶点)到观察者的位置的向量。对于正交投影,眼睛位置的向量被替换为负视图方向,这对于场景是恒定的,计算这个向量和三角形的法向量的点积,点积为负意味着两个向量之间的夹角大于π/2弧度,所以三角形不是面向观察者的,这个测试等价于计算从观察者的位置到三角形平面的标记距离,如果符号是正的,三角形是正面的。注意,只有在法线被标准化的情况下才能得到距离,但在这里这并不重要,因为我们感兴趣的只有符号。或者,应用投影矩阵后,在clip空间中形成顶点  ,并计算行列式  ,如果d≤0,则可以剔除三角形,这些剔除技术如图所示:

确定三角形是否背面的两个不同的测试。 左图显示了是如何在屏幕空间中完成测试的。 左边的两个三角形是正面的,右边的三角形是背面的,可以剔除。 右图显示了如何在视图空间中完成背面测试, 三角形A和B是正面的,而C是背面的。

Blinn指出,这两种测试在几何上是相同的,理论上,区分这些测试的是计算测试的空间,而不是其他。在实践中,屏幕空间测试通常更安全,因为在视图空间中看起来稍微向后的三角形边在屏幕空间中可能会稍微向前,这是因为视图空间坐标通过四舍五入转换为屏幕空间的亚像素坐标。

使用诸如OpenGL或DirectX之类的API,背面剔除通常通过一些函数来控制,这些函数要么启用背面剔除,要么启用正面剔除,要么禁用所有剔除。 请注意,镜像变换(即负缩放操作)将面向后的三角形变成面向前的三角形,反之亦然(章节4.1.3)。 最后,可以在像素着色器中找出一个三角形是否是正面的。 在OpenGL中,这是通过测试glFrontFacing来完成的,在DirectX中它被称为SV_IsFrontFace。 在此之前,正确显示双面物体的主要方法是将它们渲染两次,首先剔除背面,然后剔除正面,并反转法线。

关于标准背面剔除的一个常见误解是,它减少了大约一半的三角形渲染的数量。 虽然背面剔除将移除许多物体中大约一半的三角形,但它将为某些类型的模型提供很少的增益。 例如,室内场景的墙壁、地板和天花板通常是面向观众的,所以在这些场景中,这些类型的背面相对较少。 类似地,在地形渲染中,大多数三角形都是可见的,只有那些在山或峡谷的背面的三角形受益于这种技术。

虽然背面剔除是一种避免对单独的三角形进行光栅化的简单技术,但如果可以通过一个测试来决定是否可以剔除整个三角形集合,那么它将会更快。这些技术被称为集群背面剔除算法,我们将在这里回顾其中的一些。许多这样的算法使用的基本概念是法向锥,对于曲面的某些部分,创建一个裁剪锥,它包含所有的法线方向和所有的点。注意,沿着法线的两段距离需要截断圆锥体,如图:

左: 一组三角形及其法线。 左中:法线(上),最小锥(下),由一个法线n,半角α 定义。 中右:圆锥被锚定在点c上,并被截断,以便它也包含三角形上的所有点。 右图:截去的圆锥的横截面。 顶部的浅灰色区域为前视锥,底部的浅灰色区域为后视锥。 点f和点b分别是前锥和后锥的顶点。

可以看出,圆锥是由法线n和半角α和锚点c以及沿法线截断圆锥的一些偏移距离定义的,在上图的右侧,一个法向锥的横截面被显示出来。Shirman和Abi-Ezzi证明,如果观察者面向锥体,那么锥体中的所有面都是面向前的,面向后的锥体也是如此,Engel使用了一个类似的概念,称为GPU剔除的排除体积。

对于静态网格,Haar和Aaltonen建议在n个三角形周围计算一个最小的立方体,每个立方体面被分割成r×r“像素”,每个编码一个n位掩码,表示对应的三角形是否在该“像素”上可见。 如图所示:

一组有五个静态三角形,从边缘上看,被二维的正方形包围着。 左边的方形面被分割成4个“像素”,我们关注从顶部开始的一秒,它在盒子外面的视锥被涂成蓝色。 三角形平面形成的正半空间,用一个半圆(红色和绿色)表示。 所有三角形在其正半空间中没有蓝色截锥的任何部分,都从视锥的所有点为背面(标记为红色), 绿色表示那些正面的。

如果相机在立方体外面,就可以找到相机所在的相应视锥,并且可以立即查找它的位掩码并知道哪些三角形是背向的。 如果摄像机在立方体内部,所有三角形都被认为是可见的(除非有人想要执行进一步的计算)。 Haar和altonen在每个立方体面只使用一个位掩码,一次编码n = 64个三角形。 通过计算位掩码中设置的比特数,可以有效地为未剔除的三角形分配内存。 《刺客信条:Unity》也使用了这种方法。

接下来,我们将使用一个未截断的法向锥,它仅由中心点c、法向n和角度α定义。 要计算这样一个由多个三角形组成的法向锥,取三角形平面的所有法线,将它们放在相同的位置,在包含所有法线的单位球面上计算一个最小圆。 作为第一步,假设从点e开始,我们要测试圆锥中共享原点c的所有法线。 如果下列条件成立:

然而,此测试仅在所有几何图形位于c处时有效。接下来,我们假设所有几何图形位于圆心为c、半径为r的球体内 :

其中sin β = r/||c−e||。 推导这个测试所涉及的几何图形如下图所示。 Quantized法线可以存储在8 × 4位中,这对于某些应用可能已经足够了。

这种法向锥,定义为c, n,α, 半径r和中心c点的圆对e可见。注意,法向锥已经从c向下平移,所以它的原点与球面边界重合。

最后,我们注意到,对于运动模糊三角形(每个顶点在一帧上都有一个线性运动)的背面剔除并不像人们想象的那么简单。 一个顶点随时间线性移动的三角形可以在一帧开始时向后转,然后再向后转,所有这些都在同一帧内。 因此,如果在帧的开始和结束时由于运动模糊的三角形面向背面而剔除三角形,将会产生不正确的结果。 Munkberg和Akenine-M¨oller提出了一种将标准背面测试中的顶点替换为线性移动三角形顶点的方法。 将检验重写为Bernstein形式,并利用B´ezier曲线的凸性作为保守检验。 对于景深,如果整个镜头在三角形的负半空间(换句话说,在它后面),三角形可以被安全地剔除。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值