斜视锥体深度投影和裁剪-Oblique View Frustum Depth Projection and Clipping

发表于2016-04-23
评论1 1.18w浏览

斜视锥体深度投影和裁剪

-Oblique View Frustum

Depth Projection and Clipping

Eric Lengyel

Terathon Software

lengyel@terathon.com

  原文:http://www.terathon.com/lengyel/Lengyel-Oblique.pdf

  翻译:则卷大明

翻译不当之处请谅解,如有谬误恳请指出。


专有名词

1、View frustum,这里译作视锥体,也有翻译成视见体的。

2、Camera space,这里译作摄像机空间,其他书籍有译作视点空间的。

3、Clip space,这里译作裁剪空间。

4、Near plane/far plane,近裁剪面/远裁剪面。

5、perspective projection matrix,透视投影矩阵

6、normalized device coordinate,规范化设备坐标


摘要

  一些3D渲染技术已经从一部分的最终图像中被开发出来,这些图像来自于在场景中跟主摄像机位置不同的虚拟摄像机的渲染结果。在这些情况下,通常有一个平坦的表面,例如一个镜子的反射平面,它需要考虑被重复渲染的图片的物理包围盒。为了防止出现渲染的几何体穿透虚拟摄像机透视图的包围盒,一个附加的裁剪面必须被加入到标准的六面视锥体中。然而,一些3D图形处理器并不支持额外的平面裁剪,或者它需要额外的顶点或者像素着色器来显式地执行附加的裁剪操作。

  这篇论文讨论了一种技术,它通过修改透视矩阵这种方式,使得传统的视锥体的近裁剪面能适合于一般的斜边界裁剪平面。通过保持裁剪面的总数为六来避免性能损失和开发多套有关用户定义裁剪面的着色器的负担。近裁剪面被移动是不会影响其他四个面的,但是移动传统的远裁剪面被毁灭是不可避免地。我们分析其在远裁剪平面上的影响和受到影响的深度缓冲精度,然后提出一种构建最优的倾斜视锥体的方法。


1、介绍

  许多技术已经被开发出来用于渲染3D图像,这些技术包含的某些元素在本质上是重复的。举一些例子像镜子反射他们周围实时环境,能够看到场景中遥远地区的入口,和应用水面的折射透明度。每一种情况下都要求场景的一部分从一些虚拟摄像机的透视图中被渲染,这些虚拟摄像机的位置和姿态根据某些规则被计算出来,这些规则考虑到用户观察的主摄像机的位置。例如,利用主摄像机通过镜子平面中的反射摄像机渲染出可见的图片。

  一旦这样一个图片的组成部分通过一个虚拟摄像机被渲染出来,它通常作为一个从主摄像机的透视图中渲染的几何平面物体。这个平面被选择来替代图片仅仅是这个平面能分割其余的环境,如一面镜子,入口或者水面。在虚拟摄像机渲染的过程中,有可能几何体比替代镜子的平面更靠近摄像机,入口等。如果这个几何体被渲染,它会导致在最终图像中出现不必要的结果。这个问题最简单的解决方案是用一个用户定义的裁剪面截断所有在表面上的几何体。不幸的是,老式显卡不支持在硬件上使用用户定义裁剪平面,当启用用户定义裁剪平面时,它们必须借助于一个软件顶点处理路径。后面的显卡支持一般的用户定义裁剪操作,但是使用它们要求修改顶点或者像素着色程序——这个工作可能不太方便,因为它对每个需要保持特定几何体的着色程序需要两个版本。

  本文提出一种替代解决方案,它利用存在于每个已被渲染的场景中的裁剪面。通常,每个原始几何体在六个面的视锥体中被裁剪:四个侧面,一个近裁剪面和一个远裁剪面。添加一个第七个裁剪面,代表我们看到的表面,它总是导致和近裁剪面产生冗余,因为我们现在使用一个平面进行裁剪的操作将切割视锥体使之远离摄像机。因此,我们的策略是修改透视矩阵,通过这种方式,传统近裁剪面根据新加的裁剪面被重定位,相比较于普通视锥体,它通常是倾斜的。因为我们仍然只裁剪六个平面,这样的修改给我们想要的结果而几乎没有性能消耗。此外,这种技术可以应用于任何投影矩阵,包括传统的透视投影和正射投影以及用于模板阴影体积算法的无限投影矩阵。移动近裁剪面对视锥体的四个侧面并不会有影响,但是这种行为通常对不是通过herein描述的点对点实现技术解决的传统远裁剪面有一个不直观不利的影响。相关的影响在深度值映射上一样有危害。这种不良后果的补救措施是有限的,但是我们在这篇文章中分析这个问题并提出一个方法对给出的任何近裁剪面构建最优倾斜视锥体。


2背景

  本文描述的技术是基于OpenGL架构的背景提出的,因此我们采用OpenGL库所使用的数学表示和坐标系统。OpenGL库,对其他图形系统,如Direct3D,在摄像机坐标系和裁剪坐标系上略有不同,下一节中的推导可以被重新应用以获取一个等效的结果。

一个平面C在数学上用四维向量形式表示为:


                            (1)


其中N是指向平面正面的法向量,Q是位于平面上的任意一点。当且仅当四维点乘运算为0,则一个齐次坐标表示的点位于平面上。如果平面C的法向量N是单位长度并且,那么点乘表示点P到平面C的有符号垂直距离。

  一个平面是一个协变向量,因此必须使用矩阵逆的转置从一个坐标系转换到另外一个坐标系。当使用透视矩阵转换平面时,这是特别重要的,因为它是非正交投影矩阵(补充:正交矩阵其转置的逆是本身)。给定一个摄像机空间中的点P和一个摄像机空间中的平面C,用四分列向量表示,下面表示投影矩阵M生成裁剪空间中的点P’和一个裁剪空间中的平面C’:


              (2)


逆转这些方程允许我们从裁剪空间变换到摄像机空间。

回想OpenGL中的摄像机空间,摄像机位于原点并朝向Z轴负方向,如图1所示。为了构成右手坐标系,X轴要指向右边,Y轴朝向上面。顶点通常通过model-view矩阵从他们被指定的坐标系转换到摄像机坐标系。在这篇文章中,我们不关心model-view矩阵并且假设顶点的位置被指定在摄像机坐标系中。



图1.摄像机空间和标准的视锥体。近裁剪面和远裁剪面垂直于z轴并且距离摄像机的距离分别是n和f。 

标准视锥体是由六面平截头体包围的对摄像机可见的体积空间。如图1所示,它是由四个侧面包围起来的代表了视口的边界,近裁剪面是z=-n,远裁剪面是z=-f。近裁剪面和远裁剪面通常垂直于摄像机的观察方向,但是我们对投影矩阵的修改将会移动这两个平面并且改变视锥体的基本形状。

投影矩阵将顶点从摄像机空间变换到齐次裁剪空间。在齐次裁剪空间,一个四维的点(x, y, z, w)如果满足下列条件则说明其位于摄像机空间中的视锥体的矩阵中。


               

             (3)

使用w坐标执行透视除法将点移动到规范化设备坐标轴上,每个在视锥体中的坐标点都位于[-1, 1]区间内。我们的目标是修改投影矩阵以便于顶点能位于给定的Z坐标为-1的任意规范化平面上。我们避免检查投影矩阵的任意特定形式并且只需要它是可逆的。这允许我们的结果适用于任意投影矩阵,有可能这些投影矩阵已经在标准形式基础上经历了一些修改。

图2显示了在四维齐次裁剪空间中一个三维切片的x和z分量。在这个切片中,每个点的w坐标都为1,并且等式3所描述的视锥体的投影矩阵被一个形成立方体的六个面所限制。每个平面的w坐标都是1,并且实际上x、y和z坐标是,如表1所示。给定一个任意的投影矩阵M,等式2的逆可以被用于映射这些平面到摄像机空间。由此得出在表1列出的非常简单的公式,在这些公式中每个处于摄像机空间的平面被表示成投影矩阵2中的两个行向量的和或者差。



图2.齐次裁剪空间中w=1处的三维切片的x和z分量。

 表1.裁剪空间和摄像机空间中视锥体的各个平面。M矩阵代表投影矩阵,能将顶点从摄像机空间转换到裁剪空间。符号表示M矩阵的第i行。



3裁剪平面修改

表示图3所示的平面,在摄像机空间中指定坐标,这就是我们想要用来裁剪我们的几何体。摄像机应该位于平面的背面,所以我们可以假设。平面C将会替代普通的视锥体近裁剪面。在表1中所示,摄像机空间中的近裁剪面可以用投影矩阵M的最后两个行向量的和来表示,所以我们必须在某种程度上满足:


              (4)


我们不能修改投影矩阵的第四个行向量,因为透视投影矩阵使用它移动-z坐标到w坐标,这是通过插值顶点纹理坐标等属性来达到透视上的正确所必须的。因此,我们没有其他的选择只剩下替换投影矩阵的第三行,即:



图3.使用自定义平面C替代视锥体的近裁剪面


 

                            (5)

在使用等式5做替换后,视锥体的远裁剪面F就变成了:


                            (6)


这个公式给透视投影带来了一个重大的问题。一个透视投影矩阵必须要有一个由给出的第四行以便于裁剪空间的w坐标接收摄像机空间负z坐标。因此,如果或者是非零那么近裁剪面和远裁剪面就不再平行。这非常的不直观并且导致了视锥体有一个不理想的形状。通过观察,满足的任意一点P(x, y, 0, w),我们可以推断出它也满足,我们可以得出一个结论,近裁剪面和远裁剪面的交集在x-y平面上,如图4(a)所示。由于点的最大投影深度是在远裁剪面上,所以投射的深度值不再表示沿着Z轴的距离,而是一个跟新的近裁剪面和远裁剪面有关的值。这对在视锥体中沿着不同方向的深度值的精确度有严重的影响,幸运的是,我们有一个将这个影响最小化的补偿措施,就是使近裁剪面和远裁剪面的夹角尽可能的小。平面C有一个隐藏的不受限制的缩放因子。改变C平面的缩放将会导致远裁剪面F朝向的改变,所以我们需要计算一个合适的缩放来使C和F之间的夹角最小化并且不裁剪掉原视锥体的任何部分,如图4(b)所示。

将新的近裁剪面投射到裁剪空间(使用原投影矩阵M)。在C平面的对边上的视锥体的角Q可以通过下面公式给出:



(对绝大多数透视投影矩阵,可以安全的假设符号是和相等,所以将C投射到裁剪空间的操作可以被忽略。)一旦我们决定了Q’,我们就可以通过公式获得在摄像机空间中对应的Q。对一个标准的视锥体来说,Q等同于两个侧面与远裁剪面相交的离C平面最远的点。

为了使远裁剪面包含点Q,我们必须保证。我们唯一可以对等式6修改的部分是C平面的缩放,所以我们可以引入一个因子,如下所示。


.                            (8)


解方程得到:


.                            (9)


 


 


图4.(a)通过等式6得出的修改过的远裁剪面F与修改过的C平面相交于x-y平面.(b)根据等式9得出的值缩放近裁剪面C以适合远裁剪面,使得近裁剪面和远裁剪面之间的夹角尽可能的小并且不裁剪掉原视锥体的任何部分。阴影部分代表的体积空间不会被修改过的视锥体所裁剪。

 

在等式5中,使用替换C得出:


                            (10)


  这将生成最优的远裁剪面朝向,如图4(b)所示。需要注意的是,这种技术对于无限投影矩阵M同样也能正确工作(即,近裁剪面不变,远裁剪面在无穷远),通过迫使新远裁剪面与视锥体两侧面相交的一个边平行。


4对标准视锥体的影响

根据前面小结中提出的理论,我们现在通过标准透视投影矩阵来验证它的应用性。我们同样分析斜近裁剪面在深度缓冲精度上的影响。标准的OpenGL透视投影矩阵M如下所示:


,                            (11)


n是指到近裁剪面的距离,f是到远裁剪面的距离,符号表示视锥体[3]中的四个构成矩形的侧面left、right、bottom和top。M矩阵的逆如下所示:

 


,                            (12)


  给定一个裁剪面C,联立等式(9)和(10)得出下列表示被修改的投影矩阵M’的第三行的公式。


                            (13)


联立由等式(12)给出的和由等式7给出的点Q’,我们有:


.                            (15)


为了测试我们的程序对投影矩阵的修改,在这个例子中裁剪面C垂直于Z轴(即,平行于传统的近裁剪面),我们赋值C=(0,0,-1,d)以得到一个正数的距离d。我们指望的最好结果是一个新的投影矩阵它的近裁剪面从摄像机位置移动一段距离,而远裁剪面保持在它原来的位置上。使用由等式15给出的Q值,的点乘结果是简单的。求等式14的值得到投影矩阵的新的第三行:


                            (16)


我们因此得到了预期的结果,如果d=n,然后我们恢复成在等式11中所示的原投影矩阵。

正如前面提到的,修改视锥体对一个任意平面执行裁剪会影响深度缓冲的精度,因为在摄像机空间中深度值的全范围不可能被用于不同的方向。给定一个任意摄像机空间的方向向量其中,一个摄像机空间的点,其中s>0,规范化设备Z坐标由下列等式给出:


                            (17)


其中是等式9给出的缩放因子。对于,等式17有:


                            (18)


我们假设,否则就没有点会落在体空间的可视范围内。让s趋于无限,得到极限:


                            (19)


给出V方向上规范化设备Z坐标的最大值。

让我们考虑这个方向,其从摄像机位置直视前方。当条件得到满足,等式19给出的极限值小于1。在这个示例中,等式8给出的远裁剪面F的z坐标小于0,并且远裁剪平面永远不会进入视锥体四个侧面围起来的体空间中。因为远裁剪面永远无法到达方向V,其所能达到的规范化深度值的范围比普通视锥体的小。图5展示了裁剪平面在深度缓冲的利用率上定向的影响并且显示了可被考虑的精度损失。一般来说,精度会随着裁剪平面C的法线方向和Z轴的夹角的增加和摄像机到裁剪平面的距离的增加而降低。



图5.这个表面代表规范化设备z坐标能达到的最大值,根据等式19所得出,在摄像机空间方向V(0,0,-1,0)。这个表面根据近裁剪平面的法线方向和负Z轴的夹角以及摄像机到近裁剪平面的距离所绘制的。表面区域被限制在1之内,代表被修改的远裁剪平面与摄像机前方的Z轴的平面夹角。

5.结论

为了使近裁剪面被任意摄像机空间的裁剪平面C()所替代,一个任意的可逆投影矩阵M能被修改,通过构造一个如下所示新的投影矩阵M’:


                            (20)


其中,并且Q’通过等式7给出。如果M是一个透视投影矩阵,那么并且能被等式14所简化。通过最大化使用深度缓冲的有效值,这个程序构建了一个最优的视锥体。虽然深度缓冲值的精度降低了,我们发现在几乎所有的实际情况中,足够的离散深度值在用于渲染图像的标准24位深度缓冲中依然可被利用而不需要人工校正。

 

  参考文献

  [1] http://developer.nvidia.com/object/oblique_frustum_clipping.html

  [2] Eric Lengyel, Mathematics for 3D Game Programming and Computer Graphics.

  Charles River Media, 2002, p. 103.

  [3] OpenGL Architecture Review Board, The OpenGL Graphics System: A Specification.

  Silicon Graphics, Inc., 2004, p. 45.

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引