OpenGL学习笔记-十-深度测试
深度测试
深度测试用于解决像素的遮挡问题,即:哪个像素应该被显示在屏vanishing.cc20040422
幕上.
深度测试原理如下:
- 用一张纹理来存储信息
- 将每个片段与深度缓冲中的值信息进行深度测试,如果测试通过,则更新深度缓冲中的值信息,否则丢弃该片段.
启用深度测试
在OpenGL中,使用以下代码来启用深度测试:
glEnable(GL_DEPTH_TEST); |
为了防止渲染帧使用上一帧的深度缓冲,你应该在每个渲染迭代之前清除深度缓冲:
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); |
禁用写入深度缓冲
有时你可能需要禁止写入深度缓冲,例如,当你只需要渲染一个透明物体时,你可能不希望它影响深度测试.
在OpenGL中,使用以下代码来禁止写入深度缓冲:
glDepthMask(GL_FALSE); |
深度测试函数
深度测试函数用于控制OpenGL如何判断是否通过深度测试.
有以下几种深度测试函数:
- GL_ALWAYS: 总是通过测试
- GL_NEVER: 总是丢弃片段
- GL_LESS: 如果片段的深度值小于深度缓冲中的值,则通过测试
- GL_EQUAL: 如果片段的深度值等于深度缓冲中的值,则通过测试
- GL_LEQUAL: 如果片段的深度值小于或等于深度缓冲中的值,则通过测试
- GL_GREATER: 如果片段的深度值大于深度缓冲中的值,则通过测试
- GL_NOTEQUAL: 如果片段的深度值不等于深度缓冲中的值,则通过测试
- GL_GEQUAL: 如果片段的深度值大于或等于深度缓冲中的值,则通过测试
使用此函数来设置深度测试函数:
glDepthFunc(GL_LESS); |
深度映射
我们知道深度值是[0,1]的范围.
因此深度值和z值的关系可以使用以下公式:
问题在于: 对于远处的物体,我们对精度的要求没有近处的高.
所以实践中都是使用非线性的方程:
这个方程和1/z成正比.
看看你的深度缓冲
如果我们直接将深度缓冲的值作为颜色输出,我们就可以直观看到场景的深度值.
void main() { |
gl_FragCoord 是OpenGL提供的内置变量,它包含了片段的位置信息.
深度冲突
当深度值精度不够时,就会出现深度冲突.
比如一幅画贴在墙上,好巧不巧,墙离摄像机距离又很远(精度更低).
就很容易出现墙和画交叠闪烁的画面.
深度冲突是一个系统性误差,换言之无法解决只能尽量避免.
有这些手段:
- 使用更高精度的深度缓冲
- 将近平面尽可能设置远
- 不要把物体摆太近
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 VanishingBlog!