ZTest

深度测试相关(ZTest)

在不使用深度测试的时候,如果我们先绘制一个距离较近的物体,再绘制距离较远的物体,则距离远的物体因为后绘制,会把距离近的物体覆盖掉,这样的效果并不是我们所希望的。而有了深度缓冲以后,绘制物体的顺序就不那么重要了,都能按照远近(Z值)正常显示,这很关键。

深度

深度为该像素点离摄像机的距离(z值),存在深度缓冲中,通常会以16、24、32位float来存储,精度越高越精确。通常为24位

深度测试

将该像素点的z值对比G-Buffer的值,通过则更新为新的深度值,测试失败则丢弃该片段

深度缓冲

深度缓冲中存着深度数据,由于深度缓冲是在片段着色器运行后在屏幕空间进行,现在大部分的GPU都提供一个叫做提前深度测试(Early Depth Testing)的硬件特性。提前深度测试允许深度测试在片段着色器之前运行。只要我们清楚一个片段永远不会是可见的(它在其他物体之后),我们就能提前丢弃这个片段。

深度值精度

深度缓冲包含一个介于0.0和1.0之前的值,里面存着深度值为距离摄像机的距离,但几乎永远不会使用这样的线性深度缓冲(Linear Depth Buffer)的。要想有正确的投影性质,需要使用一个非线性的深度方程,它是与 1/z 成正比的。它做的就是在z值很小的时候提供非常高的精度,而在z值很远的时候提供更少的精度。这样才能更大的利用深度值的精度。

由于非线性方程与 1/z 成正比,在1.0和2.0之间的z值将会变换至1.0到0.5之间的深度值,这就是一个float提供给我们的一半精度了,这在z值很小的情况下提供了非常大的精度。在50.0和100.0之间的z值将会只占2%的float精度,这正是我们所需要的。这样的一个考虑了远近距离的方程是这样的:

变成图大概是这样

深度冲突

一个很常见的错误是俩个平面紧密贴在一起时,深度缓冲没有足够的精度来决定谁在前面,就会出现交替闪烁的现象,叫深度冲突(Z-fighting)

抗深度冲突技术中,最简单的就是使用更高的精度深度缓冲,会牺牲掉一些性能,却能获得更好的效果。