OpenGL | 深度缓冲区Z-buffer

一、隐藏面消除

在绘制3D场景的时候,我们需要决定哪些部分对观察者是可见的,或者说哪些部分对观察者不可见,对于不可见的部分,我们应该及早的丢弃,例如在一个不透明的墙壁后的物体就不应该渲染。这种问题称之为隐藏面消除(Hidden surface elimination),或者称之为找出可见面(Visible surface detemination)。

二、隐藏面消除算法

1.画家算法

隐藏面消除比较简单的做法是画家算法(painter’s algorithm)。画家算法的基本思路是,先绘制场景中离观察者较远的物体,再绘制较近的物体。例如绘制下面图中的物体(来自Z buffer 和 W buffer 簡介),先绘制红色部分,再绘制黄色,最后绘制灰色部分,即可解决隐藏面消除问题。

使用画家算法时,只要将场景中物体按照离观察者的距离远近排序,由远及近的绘制即可。画家算法很简单,但另一方面也存在缺陷,例如下面的图中,三个三角形互相重叠的情况,画家算法将无法处理:

2.Z-buffer

OpenGL存储它的所有深度信息于一个Z缓冲(Z-buffer)中,也被称为深度缓冲(Depth Buffer)。GLFW会自动为你生成这样一个缓冲(就像它也有一个颜色缓冲来存储输出图像的颜色)。深度值存储在每个片段里面(作为片段的z值),当片段想要输出它的颜色时,OpenGL会将它的深度值和z缓冲进行比较,如果当前的片段在其它片段之后,它将会被丢弃,否则将会覆盖。这个过程称为深度测试(Depth Testing),它是由OpenGL自动完成的。

(1)深度测试

深度测试默认是禁用的,所以如果要启用深度测试的话,我们需要用GL_DEPTH_TEST选项来启用它:

glEnable(GL_DEPTH_TEST);

当它启用的时候,如果一个片段通过了深度测试的话,OpenGL会在深度缓冲中储存该片段的z值;如果没有通过深度缓冲,则会丢弃该片段。如果你启用了深度缓冲,你还应该在每个渲染迭代之前使用GL_DEPTH_BUFFER_BIT来清除深度缓冲,否则你仍在使用上一次渲染迭代中写入的深度值:

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

清除深度缓冲区的默认值是1.0,表示最大的深度值,深度值的范围在[0.0,1.0]之间,值越小表示越靠近观察者,值越大表示远离观察者。

(2)应用场景

绘制天空盒时,我们需要将它变为场景中的第一个渲染的物体,并且禁用深度写入。这样子天空盒就会永远被绘制在其它物体的背后了。

当接下来绘制的元素不想被当前场景中的元素覆盖(当前场景有个平面,如接下来绘制的元素位置在平面下方,但我们想让该元素在平面上方显示),可以在绘制该元素时禁用深度测试。(禁用深度测试后,当前场景的所有元素深度值都是1.0,离摄像头最远。)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

烫青菜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值