齐次裁剪矩阵(投影矩阵)ProjectionMatrix参数分析以及NDC坐标原理解释
在观察空间中,我们可以通过近平面(near plane)n,和远平面(far plane)f,垂直视场角 a 以及纵横比 r 这4个参数来表述一个以原点作为中心的视锥体。横纵比公式: r = width/height(宽除以高);
出于理解,我们把高设置为2,那么宽必须满足 r = w/h = w/2 ;w = 2r;图1为垂直视场截面,图2为水平视场截面,d为原点距离近平面的距离,α为垂直视场角,根据图我们可以求得 :
tan(α/2) = 1/d ,继而求得 d = 1/tan(α/2) 继而求得 d = cot(α/2);
再根据图2 (β 为水平视场角)求得
tan(β/2) = r/d 把上式求得的d 带入 继而求得tan(β/2) = r/cot(α/2) = r·tan(α/2)
所以,一旦给定垂直视场角α和纵横比r,我们必能求出水平视场角β
β = 2arctan(r*tan(α/2)) ;(看不懂这个公式没关系,这个只需要理解要推导出视角一定要用到α和r就行了)
图一
图二
那么我们拿到了点(x,y,z)之后如何得出在近平面得(x‘,y‘,d) 呢
通过相似三角形的性质我们可以发现:
同时可以看出如果点(x,y,z)位于近平面内,当且仅当:
NDC坐标(规格化坐标):由于在计算过程中,要保证观察空间里的投影窗口的高为2,宽为2r,但是如果投影窗口的尺寸依赖于纵横比r的话便会产生一个问题:由于硬件会涉及到一些与投影窗口大小有关的操作(比如将投影窗口映射到后台缓冲区等),这表示我们还需要将r告诉硬件,所以如果能去除横纵比r的以来,那么处理过程会更简单,这就是ndc坐标的由来,对此,我们的解决办法是将x坐标上的投影区间从[-r,r] 缩放至区间为[-1,1]
-r≤x‘≤r
不等式除以r得:
-1≤x‘/r≤1
得此映射之后,x坐标和y得坐标成为了ndc坐标。此时,若点(x,y,z)位于近平面之中,得:
我们可以直接求出以ndc坐标来表示得x轴和y轴上得投影坐标:
注意,在ndc坐标中,投影得窗口得高和宽都是2,所以它的大小是固定的,硬件也就无需知道纵横比,但是我们一定要确保将投影坐标映射到ndc空间内。
投影矩阵
由于上图中得公式为非线性公式,我们一分为二,将线性和非线性拆分开处理,非线性部分要除以z的计算过程。我们还将对z坐标进行归一化处理;这意味着在执行非线性部分除以z的计算时,我们却无最初的z坐标可用。也就是说,我们一定要在此变换之前保存早先传入的初始z坐标。为了做到这一点,我们要利用齐次坐标将输入的z坐标复制到输出的w坐标。根据矩阵的乘法运算法则,需要令元素[2][3] = 1以及元素[2][3] = 0来加以实现(这里采用的是以0为基准的索引)。
可以看到,我们在矩阵中设置了常量A和常量B,利用他们即可把输入的z坐标变换到归一化范围。令任意点(x,y,z,1)与该矩阵相乘将会得到:
在顶点与投影矩阵相乘之后(即线性部分),我们还要通过将每个坐标分别除以w = z(即非线性部分来完成整个变换过程)
图4
归一化z深度文章来源:https://www.toymoban.com/news/detail-840510.html
前面我们说到要用矩阵表示投影关系,得到了一个公式是由线性部分和非线性部分组成,我们把线性和非线性的部分提取出来,把线性部分放到m11和m22的位置,留下一个非线性的z保留进矩阵的剩余部分,为了实现深度缓冲算法,我们任然需要保留这些3D的深度信息,就像Direct3D希望把x、y坐标映射归一化范围一样,深度坐标需要归一化区间为[0,1]以内。我们设立一个g(z)来把z坐标从区间[n,f]映射到0、1之间。由于该函数具有保序性,即归一化处理之后,深度关系保持不变。
从图4的公式可以看出,z坐标经过一下变换的处理
现在,我们需要根据下列约束求出对应的A和B:
得:
把B带入条件,解得A
所以:
根据函数g得图像可以看出,他是严格递增得非线性函数
既然已经求得了A和B,我们就可以确定出完整得透视投影矩阵
在顶点乘以投影矩阵之后但还未进行透视剔除法之前,几何体会处于所谓的齐次裁剪空间(clip space)或投影空间中。待完成透视除法之后,便是用规格化设备坐标(NDC)来表示几何体了。文章来源地址https://www.toymoban.com/news/detail-840510.html
到了这里,关于齐次裁剪矩阵(投影矩阵)ProjectionMatrix参数分析以及NDC坐标原理解释的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!