学习立方体贴图(skybox)的时候,在优化那里,有这么一段话:
一开始我还有些纳闷,想着透视除法不是通过透视矩阵自动操作的嘛,还有z分量怎么就是深度值了?不是应该通过上次深度测试所给的函数才对吗?
带着这些疑问,我重新查阅了一些资料,也看了透视矩阵的推导过程。
实际上,我以前的想法有些许错误,在顶点着色器中,物体只进行的MVP操作(M:model, V:view, P:perspective),并不会做透视除法的操作,透视除法是在顶点着色器运行之后进行的。
物体进行MVP操作的时候,vertex shader最后的输出值是在clip space(裁剪空间)上,接着GPU自己做透视除法,将顶点转化到NDC上。也就是说,在我之前的博客里面说过的透视除法是为了体现“近大远小”的说法是错的(近大远小通过透视矩阵(也称投影矩阵)体现才对),透视除法是为了将4D的裁剪空间坐标转化成3D的标准设备坐标。
那么自然而然的,透视除法之后的Z分量的确就是物体实际的深度值没错,此时这个Z分量的取值范围是[-1, 1](NDC),但是,深度缓冲中的深度值的取值范围却定义为[0, 1],为了让物体实际的深度值(Z分量)和深度缓冲中的深度值可以在同一度量下进行比较,我们需要将物体实际的深度值映射(map)到[0, 1]的范围,所以才有了前面博客的Z-value的“计算函数”,实际上那不是计算函数,只是映射罢了。
而由于越近的物体细节越多,越远的物体细节越少,因此这个映射不能是简单的线性映射,而应该通过某些非线性函数计算出来。
ps: w分量是透视矩阵自动设置的。
之前关于深度缓冲的博客我改了一些,但是难以保证全改了,因此重新写一篇注意一下。
至于透视矩阵怎么来的,参照这里: