概述
在渲染管线中的顶点变换中,介绍了顶点在各个坐标空间的变换。变换到最后,是屏幕坐标空间。在OpenGL中,屏幕空间坐标的Z值即是深度缓冲中的深度值。深度缓冲包含了一个介于0.0和1.0之间的深度值,它将会与观察者视角所看见的场景中所有物体的z值进行比较。本文将介绍深度值的计算,以及从深度值反向计算出相机空间中的顶点的Z值。
深度值计算
在渲染管线中的顶点变换中,计算得到了透视投影矩阵:
同时,也得到了视口变换矩阵:
首先,根据透视矩阵,计算NDC空间的Z值。这里,相机空间中的坐标经过透视矩阵变换后,还要进行齐次除法,才能得到NDC空间中的坐标。
由此,可以得出:
根据上述公式,可以得出:
根据视口变换矩阵,可以得出:
将带入,可以得到:
即:
到这一步,即可以求得屏幕空间中的深度。
在Learn OpenGL CN学习过的,可能对深度测试这一节的内容有些印象。它得到的深度值的公式是:
跟式对比,发现有些不一样,这是怎么回事呢?
这里要注意,本文定义的、和是实际的坐标值,是负的。而深度测试文中,定义的、代表了近平面和远平面,而代表了近、远平面之间的值,它们都是正的。将、、代入式,可得:
深度值的线性可视化
经过上面的推导,我们得出了深度值的计算公式。
现在,反过来,我们知道了屏幕空间中的深度值,怎么求出相机空间中的深度值呢?
首先,根据,可以推导出:
对于公式2,得出的是实际坐标的值。为了和OpenGL中的定义统一,也将、和代入公式,可以得到:
在深度测试这一节中,得出的公式是:
对比发现,跟公式有些不一样。这是因为,求出的是顶点距离相机的距离,是正值。而是顶点的实际坐标,是负值,将取反,即可得到。
至此,推导完成。
参考
- [1] 深度测试
- [2] 渲染管线中的顶点变换
网友评论