美文网首页
OpenGL-深度测试

OpenGL-深度测试

作者: 我的大好时光 | 来源:发表于2018-03-07 13:55 被阅读75次

本节了解的内容

  • 什么叫做深度缓冲区。
  • 深度缓冲区的作用。
  • 如何使用深度缓冲区测试。
  • 可视化深度值。
  • 如何解决深度值相同,造成的冲突问题。

问题背景

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

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

简书.png
使用画家算法时,只要将场景中物体按照离观察者的距离远近排序,由远及近的绘制即可。画家算法很简单,但另一方面也存在缺陷,例如下面的图中,三个三角形互相重叠的情况,画家算法将无法处理:
简书1.png
解决隐藏面消除问题的算法有很多,具体可以参考Visible Surface Detection。结合OpenGL,我们使用的是Z-buffer方法,也叫深度缓冲区Depth-buffer。

深度缓冲区(Detph buffer)同颜色缓冲区(color buffer)是对应的,颜色缓冲区存储的像素的颜色信息,而深度缓冲区存储像素的深度信息。

在决定是否绘制一个物体的表面时,首先将表面对应像素的深度值与当前深度缓冲区中的值进行比较,如果大于等于深度缓冲区中值,则丢弃这部分;否则利用这个像素对应的深度值和颜色值,分别更新深度缓冲区和颜色缓冲区。这一过程称之为深度测试(Depth Testing)

OpenGL中使用深度测试

深度缓冲区一般由窗口管理系统,例如GLFW来创建,深度值一般由16位,24位或者32位值表示,通常是24位。位数越高的话,深度的精确度越好。首先我们开始深度测试

   glEnable(GL_DEPTH_TEST);

另外还需要在绘制场景前,清除颜色缓冲区时,清除深度缓冲区:

  glClearColor(0.18f, 0.04f, 0.14f, 1.0f);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

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

上面提到了在进行深度测试时,当前深度值和深度缓冲区中的深度值,进行比较的函数,可以由用户通过glDepthFunc指定,这个函数包括一个参数,具体的参数如下表所示:

简书2.png

例如我们可以使用GL_AWALYS参数,这与默认不开启深度测试效果是一样的:

 glDepthFunc(GL_ALWAYS);

与深度缓冲区相关的另一个函数是glDepthMask,它的参数是布尔类型,GL_FALSE将关闭缓冲区写入,默认是GL_TRUE,开启了深度缓冲区写入。

可视化深度值

深度值,实际上是屏幕坐标系下的zwin坐标,屏幕坐标系下的(x,y)坐标分别表示屏幕坐标系下以左下角(0,0)为起始点的坐标

预防ZFighting的方法

其实ZFighting就是深度值相同时,引发的冲突问题。

  • 不要将两个物体靠的太近,避免渲染时三角形叠在一起。这种方式要求对场景中物体插入一个少量的偏移,那么就可能避免ZFighting现象。例如上面的立方体和平面问题中,将平面下移0.001f就可以解决这个问题。当然手动去插入这个小的偏移是要付出代价的。

  • 采用glPolygonOffet函数,使的可以调节片段的深度值, 使深度值进行偏移而不产生悬浮。

  • 尽可能将近裁剪面设置得离观察者远一些。上面我们看到,在近裁剪平面附近,深度的精确度是很高的,因此尽可能让近裁剪面远一些的话,会使整个裁剪范围内的精确度变高一些。但是这种方式会使离观察者较近的物体被裁减掉,因此需要调试好裁剪面参数。

  • 使用更高位数的深度缓冲区,通常使用的深度缓冲区是24位的,现在有一些硬件使用使用32位的缓冲区,使精确度得到提高。

参考资料

1.www.learnopengl.com Depth testing
2.深度值计算 Real depth in OpenGL / GLSL
3.提供了深度值在线计算程序
4.opengl wiki Depth_Buffer_Precision
5.Z-buffering
6.SO讨论
7.http://blog.csdn.net/wangdingqiaoit/article/details/52206602

相关文章

网友评论

      本文标题:OpenGL-深度测试

      本文链接:https://www.haomeiwen.com/subject/lecjfftx.html