美文网首页
五、OpenGL深度测试理解

五、OpenGL深度测试理解

作者: 随意昵称你能懂得 | 来源:发表于2020-07-15 09:09 被阅读0次

深度的相关概念

什么是深度?

像素点的深度其实就该像素点在3D世界中距离摄像机的距离,Z轴距离。

什么是深度缓冲(缓存)区?

和帧缓冲区一样,就是一块内存区域(显存中)。专门存储每个像素点(绘制在屏幕上的)的深度值,和素点一一对应,每个像素点在深度缓冲区对应存储一个深度值。

如果观察者在Z轴的正方向,则Z值越大越靠近观察者。
如果观察者在Z轴的负方向,则Z值越小越靠近观察者。

为什么要使用深度缓冲区?

在不使用深度测试的时候,如果我们先绘制一个距离比较近的物体,再绘制距离较远的物体。则距离远的物体因为后绘制,会把距离近的物体覆盖掉。有了深度缓冲区后,绘制物体的顺序就不那么重要了。 实际上,只要存在深度缓冲区,OpenGL都会把像素的深度值写⼊到缓冲区中。

深度测试

深度缓冲区和颜⾊缓存区是对应的,颜⾊缓存区存储像素的颜⾊信息,⽽深度 缓冲区存储像素的深度信息。当我们之后要绘制一个物体表面的时候,首先会将表面像素点的深度与当前深度缓存区对应的深度进行比较,如果是大于深度缓存区对应的深度,则丢弃这部分值;否则的话,则使用当前像素点的颜色和深度更新颜色缓存区和深度缓存区。而这个丢弃和比较的过程,就是深度测试

如何操作深度测试

打开与关闭

//打开深度测试(默认打开)
glEnable(GL_DEPTH_TEST);
//关闭深度测试
glDisable(GL_DEPTH_TEST);

规则修改

参数 说明
GL_ALWAYS 总是通过测试
GL_NEVER 总是不通过测试
GL_LESS 当前深度值 < 存储的深度值时通过
GL_EQUAL 当前深度值 = 存储的深度值时通过
GL_LEQUAL 当前深度值 <= 存储的深度值时通过
GL_GREATER 当前深度值 > 存储的深度值时通过
GL_NOTEQUAL 当前深度值 != 存储的深度值时通过
GL_GEQUAL 当前深度值 >= 存储的深度值时通过

深度测试ZFighting闪烁问题

深度测试也同样存在着问题: ZFighting
开启深度测试之后,前后覆盖的问题得到了解决。但是由于精度的限制,对于相差非常小的深度值来说(例如在两个物体在深度上相互交叉),OpenGL可能会出现无法正确判断深度值的情况,从而导致测试结果随机出现,造成了画面交替显示,产生闪烁的问题。这就是Z-Fighting闪烁问题。如下图

ZFighting闪烁

ZFighting问题解决

目前OpenGL对Z-Fighting闪烁问题提供了一个解决方案,那就是多边形偏移( Polygon Offset)

//启用多边形偏移,参数一般使用填充即可
glEnable(GL_POLYGON_OFFSET_FILL);
//关闭多边形偏移,参数必须要和开启的时候一样
glDisable(GL_POLYGON_OFFSET_FILL);

另外还可指定偏移量

//指定多边形偏移量
void glPolygonOffset(GLFloat factor,GLFloat units);

两个参数的计算方式为:

Offset = ( m * factor ) + ( r * units);

m : 多边形的深度的斜率的最⼤值,一个多边形越是与近裁剪面平行 m 就越接近于0。
r : 能产生于窗⼝坐标系的深度值中可分辨的差异最⼩值。 r 具体是由 OpenGL 平台指定的 ⼀个常量。
一个大于0的 Offset 会把模型推到离你(摄像机)更远的位置,相应的⼀个小于0的 Offset 会把模型拉近。
一般⽽言,只需要将 -1.0 和 -1 这样简单赋值给 glPolygonOffset 基本可以满⾜需求。

ZFlighting问题预防

ZFlighting问题在绘制时也可以尽可能的去避免:

  • 不要将两个物体靠的太近,避免渲染时三角形叠在一起。这种⽅式要求对场景中物体插⼊⼀个少量的偏移,那么就可能避免ZFighting现象。当然手动去插⼊这个⼩的偏移是要付出代价的。
  • 尽可能将近裁剪面设置得离观察者远一些。在近裁剪平面附近,深度的精确度是很高的,因此尽可能让近裁剪面远一些的话,会使整个裁剪范围内的精确度变高一些。但是这种方式会使离观察者较近的物体被裁减掉,因此需要调试好裁剪面参数。
  • 使⽤更⾼位数的深度缓冲区,通常使用的深度缓冲区是24位的,现在有⼀些硬件使用的是32位的缓冲区,使精确度得到提⾼。

相关文章

  • 五、OpenGL深度测试理解

    深度的相关概念 什么是深度? 像素点的深度其实就该像素点在3D世界中距离摄像机的距离,Z轴距离。 什么是深度缓冲(...

  • 六、OpenGL 渲染技巧:深度测试、多边形偏移、 混合

    OpenGL + OpenGL ES +Metal 系列文章汇总 深度测试 在上一篇五、OpenGL 渲染技巧:正...

  • OpenGL深度测试理解

    1.什么是深度测试 深度 深度在OpenGL里面表示世界坐标系中像素点的Z轴距离观察者的距离。如下图所示观察者位置...

  • OpenGL深度测试理解

    1.深度测试在什么情况下会用到 我们在使用OpenGL绘制出一个甜甜圈样式的立体图形,在旋转时,会出现前后...

  • 13. opengl高级-深度测试

    1. opengl深度测试原理,“测试”理解为“检测规则”更容易懂 关闭深度测试,后绘制的团会覆盖先绘制的纹理: ...

  • OpenGL:背面剔除和深度测试

    OpenGL:背面剔除和深度测试

  • OpenGL -- 对深度测试的理解

    深度 深度,就是像素点在3D世界中距离摄像机的距离,即Z值。 深度缓冲区 深度缓存区,就是⼀块内存区域,专门存储每...

  • OpenGL 深度测试

    什么叫深度? 所谓深度,就在坐标系中,像素Z坐标距离观察者的距离.观察者,可以在任何位置.OpenGL 会有专门有...

  • OpenGL 深度测试

    正背面剔除遗留问题 进行了背面剔除之后,当旋转到侧边时,出现了缺口的现象. 当环旋转到侧边时观察者和环的关系如上图...

  • OpenGL深度测试

    一、概念 深度:深度其实就是该像素点在3D世界中距离摄像机的距离,Z值。 深度缓冲区:深度缓存区,就是一块内存区域...

网友评论

      本文标题:五、OpenGL深度测试理解

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