1,深度测试是什么?
在默认情况是将需要绘制的新像素的z值与深度缓冲区中对应位置的z值进行比较,如果比深度缓存中的值小,那么用新像素的颜色值更新帧缓存中对应像素的颜色值。
2,深度测试开启
glEnable(GL_DEPTH_TEST);
3,什么叫提前深度测试?
现在大部分的GPU都提供一个叫做提前深度测试(Early Depth Testing)的硬件特性。提前深度测试允许深度测试在片段着色器之前运行。只要我们清楚一个片段永远不会是可见的(它在其他物体之后),我们就能提前丢弃这个片段。
片段着色器通常开销都是很大的,所以我们应该尽可能避免运行它们。当使用提前深度测试时,片段着色器的一个限制是你不能写入片段的深度值。如果一个片段着色器对它的深度值进行了写入,提前深度测试是不可能的。OpenGL不能提前知道深度值。
4,什么是深度缓冲?(保存的距离相机最近的一个片段的信息)
5,官网中所说的禁用深度测试的情况(glDepthMask(GL_FALSE);)
启用了深度测试,那么这就不适用于同时绘制不透明物体。当需要绘制半透明物体时,需注意,在绘制半透明物体时前,还需要利用glDepthMask(GL_FALSE)将深度缓冲区设置为只读形式,否则可能出现画面错误。为什么呢,因为画透明物体时,将使用混色,这时就不能继续使用深度模式,而是利用混色函数来进行混合。这一来,就可以使用混合函数绘制半透明物体了。
也就是说半透明物体不参与深度测试,但是半透明物体之前,之后的物体需要进行深度测试,需要忽略半透明物体的深度。
6,线程深度缓冲和非线性,以及使用非线性的原因
线性的公式:
非线性的公式:
由于非线性方程与 1/z 成正比,在1.0和2.0之间的z值将会变换至1.0到0.5之间的深度值,这就是一个float提供给我们的一半精度了,这在z值很小的情况下提供了非常大的精度。在50.0和100.0之间的z值将会只占2%的float精度,这正是我们所需要的,如下图趋势:
7,使用线性深度和非线性深度的区别(使用多个远近不一的箱子做测试)
线性:
非线性:
8,什么是深度冲突?
一个很常见的视觉错误会在两个平面或者三角形非常紧密地平行排列在一起时会发生,深度缓冲没有足够的精度来决定两个形状哪个在前面。结果就是这两个形状不断地在切换前后顺序,这会导致很奇怪的花纹。这个现象叫做深度冲突(Z-fighting),因为它看起来像是这两个形状在争夺(Fight)谁该处于顶端。
这两个面的深度值都是一样的,所以深度测试没有办法决定应该显示哪一个。
9,如何防止深度冲突?
(1)最重要的技巧是永远不要把多个物体摆得太靠近,以至于它们的一些三角形会重叠
(2)尽可能将近平面设置远一些
(3)另外一个很好的技巧是牺牲一些性能,使用更高精度的深度缓冲。大部分深度缓冲的精度都是24位的,但现在大部分的显卡都支持32位的深度缓冲,这将会极大地提高精度。