QT+OpenGL深度测试
本篇完整工程见gitee:QtOpenGL 对应点的tag,由turbolove提供技术支持,您可以关注博主或者私信博主
深度缓冲
在前面的文章中,我们渲染了一个3D箱子,并且运用了深度缓冲来防止阻挡的面渲染到其他面的前面。
现在大部分的GPU都提供一个叫做提前深度测试(Early Depth Testing)的硬件特性。提前深度测试允许深度测试在片段着色器之前运行。只要我们清楚一个片段永远不会是可见的(它在其他物体之后),我们就能提前丢弃这个片段。
● 深度缓冲是由窗口系统自动创建的,他会以16、24或者32位float的形式存储它的深度值。
● 当深度测试被启用的时候,OpenGL会将一个片段的深度值与深度缓冲内容对比。如果测试通过,深度缓冲将会更新为新的深度值。如果深度测试失败,片段将会被丢弃。
● 深度缓冲是在片段着色器,以及模板测试运行之后在屏幕空间中运行的
● GLSL内建变量gl_FragCoord, x和y分量代表了片段的屏幕空间坐标(其中(0, 0)位于左下角), z分量他包含了片段真正的深度值
// 开启深度测试 glEnable(GL_DEPTH_TEST); // 深度函数 glDepthFunc(GL_LESS); // 禁用深度缓冲 glDepthMask(GL_FALSE); // 清除深度缓冲 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glDepthFunc:
函数 | 描述 |
GL_ALWAYS | 永远通过深度测试 |
GL_NEVER | 永远不通过深度测试 |
GL_LESS | 在片段深度值小于缓冲的深度值时通过测试 |
GL_EQUAL | 在片段深度值等于缓冲区的深度值时通过测试 |
GL_LEQUAL | 在片段深度值小于等于缓冲区的深度值时通过测试 |
GL_GREATER | 在片段深度值大于缓冲区的深度值时通过测试 |
GL_NOTEQUAL | 在片段深度值不等于缓冲区的深度值时通过测试 |
GL_GEQUAL | 在片段深度值大于等于缓冲区的深度值时通过测试 |
深度值精度
深度缓冲包含了一个介于0.0到1.0之间的深度值:
● 片段着色器中,gl_FragCoord向量的z值
这里的near和far值是我们之前提供给投影矩阵设置可视平截头体的那个 near 和 far 值。这个方程需要平截头体中的一个z值,并将它变换到了[0, 1]的范围中
然而,在实践中是几乎永远不会使用这样的线性深度缓冲(Linear Depth Buffer)的。要想有正确的投影性质,需要使用一个非线性的深度方程,它是与 1/z 成正比的。
#version 330 core out vec4 FragColor; float near = 0.1; float far = 100.0; float LinearizeDepth(float depth) { float z = depth * 2.0 - 1.0; return (2.0 * near * far) / (far + near - z * (far - near)); } void main() { float depth = (LinearizeDepth(gl_FragCoord.z)-near) / (far-near); FragColor = vec4(vec3(depth), 1.0); }
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x0vDyX3x-1676882895765)(C:\Users\89869\Desktop\桌面文件\LearnC++\learn-c\QT+OpenGL\深度测试.png)]