高级OpenGL之深度测试

一、简介
深度缓冲就是颜色缓冲(存储所有的片断颜色)那样存储每个片段的信息,通常和颜色缓冲区有相同的宽度和高度。深度缓冲由窗口系统自动创建并将其深度值存储为 16、 24 或 32 位浮点数。在大多数系统中深度缓冲区为24位。当深度测试启用的时候, OpenGL 测试深度缓冲区内的深度值。OpenGL 执行深度测试的时候,如果此测试通过,深度缓冲内的值将被设为新的深度值。如果深度测试失败,则丢弃该片段。
深度测试在片段着色器运行之后在屏幕空间中执行的。屏幕空间坐标直接有关的视区,由OpenGL的glViewport函数给定,并且可以通过GLSL的片段着色器中内置的gl_FragCoord变量访问。gl_FragCoord的 X 和 y 表示该片段的屏幕空间坐标 ((0,0) 在左下角)。gl_FragCoord还包含一个 z 坐标,它包含了片段的实际深度值。此 z 坐标值是与深度缓冲区的内容进行比较的值。

二、深度测试
现在大多数 GPU 都支持一种称为提前深度测试(Early depth testing)的硬件功能。提前深度测试允许深度测试在片段着色器之前运行。明确一个片段永远不会可见的 (它是其它物体的后面) 我们可以更早地放弃该片段。片段着色器通常是相当费时的所以我们应该尽量避免运行它们。对片段着色器提前深度测试一个限制是,你不应该写入片段的深度值。如果片段着色器将写入其深度值,提前深度测试是不可能的,OpenGL不能事先知道深度值。
深度测试默认为关闭状态,打开可以执行:glEnable(GL_DEPTH_TEST);
一但启用了深度测试,如果片段通过深度测试,OpenGL自动在深度缓冲区存储片段的 z 值,如果深度测试失败,那么相应地丢弃该片段。如果启用深度测试,那么在每个渲染之前还应使用GL_DEPTH_BUFFER_BIT清除深度缓冲区,否则深度缓冲区将保留上一次进行深度测试时所写的深度值
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
深度测试函数有:
在这里插入图片描述

默认情况下使用GL_LESS,这将丢弃深度值高于或等于当前深度缓冲区的值的片段。
深度缓冲去可视化:
我们知道在片段渲染器的内置gl_FragCoord向量的z值包含那个片段的深度值。如果我们要把深度值作为颜色输出的话,我们可以在场景中显示所有片段的深度值。我们可以返回基于片段的深度值的颜色向量:

void main()
{
color = vec4(vec3(gl_FragCoord.z),1.0f);
}

深度冲突:
两个平面或三角形如此紧密相互平行深度缓冲区不具有足够的精度以至于无法得到哪一个靠前。结果是,这两个形状不断似乎切换顺序导致怪异出问题。这被称为深度冲突(Z-fighting),因为它看上去像形状争夺顶靠前的位置。
深度冲突是深度缓冲区的普遍问题,当对象的距离越远一般越强(因为深度缓冲区在z值非常大的时候没有很高的精度)。深度冲突还无法完全避免,但有一般的几个技巧,将有助于减轻或完全防止深度冲突在你的场景中的出现:
1、第一个也是最重要的技巧是让物体之间不要离得太近,以至于他们的三角形重叠。
2、另一个技巧是尽可能把近平面设置得远一些。
3、另外一个技巧是放弃一些性能来得到更高的深度值的精度。

三、总结
我们已经讨论过的 3 个技术是最常见和容易实现消除深度冲突的技术。还有一些其他技术需要更多的工作,仍然不会完全消除深度冲突。深度冲突是一个常见的问题,但如果你将列举的技术适当结合你可能不会真的需要处理深度冲突。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值