高级OpenGL-深度测试

OpenGL-Depthtest

1. 深度测试

深度测试被启用时,将该片段的深度值与深度缓冲中的深度值比较,如果测试通过则更新缓冲中的深度值。深度测试在片段着色器运行后,模板测试之后进行。并且仅对屏幕空间中的片段进行深度测试。

片段着色器里gl_FragCoord中的x和y分量代表片段在屏幕中的坐标,z分量就是与深度缓冲值对比的深度值。

深度测试在OpengGL中默认是禁用的,因此需要手动启用它

glEnable(GL_DEPTH_TEST);

片段的深度值没有通过测试的话,这个片段会被丢弃,因此我们需要清除深度缓冲。(顺便清除颜色缓冲)

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER-BIT);

有时候,在深度测试之后我们并不希望更新缓冲,此时我们可以将深度缓冲设置为只读。也就是将深度掩码设置为FALSE。

glDepthMask(GL_FALSE);

2. 深度测试函数

我们可以在OpenGL中控制深度测试的通过条件

函数 通过条件
GL_ALWAYS ture
GL_NEVER false
GL_LESS gl_FragCoord.z < z-buffer
GL_EQUAL gl_FragCoord.z = z-buffer
GL_LEQUAL gl_FragCoord.z <= z-buffer
GL_GREATER gl_FragCoord.z > z-buffer
GL_NOTEQUAL gl_FragCoord.z != z-buffer
GL_GEQUAL gl_FragCoord.z >= z-buffer

其中默认值为GL_LESS,即丢弃深度值大于等于当前深度缓冲中深度值的片段。

有些家长说想要看效果,那我们就来看看效果(狗头)

我在同一个位置放了两个相同大小不同颜色的方块,并在绘制时先绘制红色的方块,后绘制绿色的方块。

GL_ALWAYS时我发现绘制的是绿色的方块,并且不论如何移动相机观看显示的都是绿色的方块。

但是当GL_NOTEQUAL时,虽然绘制的也是绿色的方块,但是移动相机靠近时会发现,在一定距离内绘制的是红色方块。并且视野向下看的话,还会看到红色绿色同时出现在屏幕上的情况。

高级OpenGL-深度测试_第1张图片高级OpenGL-深度测试_第2张图片因此猜测可能是在一定距离外,深度测试的准确性并不高,此时便会判断绿色片段和红色片段的深度不相同,将红色片段替换为绿色片段,而在距离较近的情况下,判断绿色片段的深度和红色片段的深度相同,将绿色片段丢弃。

3.深度值精度

通过非线性公式,当z值很小的时候提供较高的精度,而z值较大的时候提供更少的精度。
F d e p t h = 1 / z − 1 / n e a r 1 / f a r − 1 / n e a r F_{depth}=\frac{1/z-1/near}{1/far-1/near} Fdepth=1/far1/near1/z1/near
其中near和far分别代表观察空间的近平面和远平面。

4. 深度冲突

这次我将红色方块与绿色方块的其中一个边重合,靠近一定距离会发现发生深度冲突,这是因为此时深度缓冲没有足够的精度来决定哪个在前面,因此他们不停地切换前后顺序,才形成了这样的花纹。

高级OpenGL-深度测试_第3张图片

可是当两个方块完全重合时,我们却看不到任何深度冲突的发生,这是为什么呢。我暂时还没有想到比较合理的解释。

5. 防止深度冲突

1.在物体间设置一点偏移,防止片段重合的发生,需要手动调整。

2.将观察空间的近平面设置得远一点,可以提高深度缓冲的精度,但同时近处的物体会被截掉。

3.采用更高精度的深度缓冲,但是会牺牲一部分性能。

你可能感兴趣的:(学习笔记,OpenGL)