美文网首页视觉学习
OpenGL-消除隐藏面之深度测试

OpenGL-消除隐藏面之深度测试

作者: 一代千禧 | 来源:发表于2020-07-13 10:16 被阅读0次

首先直观的感受下,在不消除隐藏面的情况下,图形旋转中会出现的场景: 正背面不消除问题图片

针对上述问题,提供两种解决方法:

1、正背面消除:根据顶点数据顺序判断用户可见部分(阳面)与隐藏面(阴面),隐藏面直接丢弃,不绘制,只绘制可见部分
2、深度测试:不管图层数量,只显示绘制可见图层,剩余不可见的直接丢弃

正背面消除:该方法不能从根本上解决上述场景的问题,会出现缺口,如下图; 缺口问题

上述场景出现的原因:甜甜圈旋转过程中,当前后两部分重叠时,OpenGL中并不能清楚地区分,两个图层谁显示在前,谁显示在后,导致甜甜圈产生了缺口。
关于正背面消除方法具体实现原理,这里不详细阐述(主要需了解下阳面,阴面的判定)

针对正背面消除方法存在的缺陷,深度测试应运而生,首先理解下以下几个概念

深度:指OpenGL坐标系中,像素点的Z坐标距观察者的距离,存在如下关系:

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

图解如下: 深度值与Z坐标值的关系(基于 观察者不动,物体动的观察方式)

深度缓存区(Depth Buffer):

指一块专门内存区域,存储在显存中,用于存储屏幕上所绘制图形的每个像素点的深度值,对应关系如下:
1、深度值越大,离观察者越远
2、深度值越小,里观察者越近
注意事项:
1、深度缓存区中,每个像素点和深度值一一对应
2、深度缓冲区的范围是[0, 1]之间,默认值是1.0,表示深度值的最大值
3、每次绘制前需清空深度缓存区,否则会存在上次绘制缓存的深度值,影响当前图形的绘制

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

深度测试:

一个物体在绘制时,像素点新的深度值与深度缓存中已经存在的深度值作比较,若新值 > 旧值,则丢弃,反之,将新的深度值更新至深度缓存区,由于深度缓存区与颜色缓存区是一一对应的,同时也需要更新该像素点的颜色值到颜色缓存区,该过程就是深度测试
开启深度测试

glEnable(GL_DEPTH_TEST);

关闭深度测试

glDisable(GL_DEPTH_TEST);
开启深度测试后,效果图如下: 开启深度测试后效果图

多边形偏移(Polygon Offset)

深度测试虽然解决了上述出现的缺口问题,但同时引出了Z-Fighting(Z冲突,闪烁)问题,发生z冲突的原因如下:开启深度测试后,由于深度缓冲区精度限制,导致深度值在误差极小时,OpenGL出现无法判断的情况,出现画面交错闪现的现象,举例如下: Z冲突剧烈

开启深度测试

glEnable(GL_POLYGON_OFFSET_FILL)

关闭深度测试

glDisable(GL_POLYGON_OFFSET_FILL)

预防解决Z冲突方法:

1、避免两个物体靠的太近:在绘制时,插入一个小偏移
指定偏移量glPolygonOffset (GLfloat factor, GLfloat units),参数一般填 -1 和 -1
2、将近裁剪面(设置透视投影时设置)设置的离观察者远一些:提高裁剪范围内的精确度
2、使用更高位数的深度缓冲区:提高深度缓冲区的精确度

相关文章

  • OpenGL-消除隐藏面之深度测试

    首先直观的感受下,在不消除隐藏面的情况下,图形旋转中会出现的场景:正背面不消除问题图片 针对上述问题,提供两种解决...

  • OpenGL-10-渲染技巧:深度测试、多边形偏移、颜色混合

    上篇文章提到了 深度测试 可以解决隐藏面消除。这次来深入理解一下深度测试,以及深度测试带来的问题和解决方法:多边形...

  • OpenGL-多边形偏移和颜色混合

    上一篇文章我们讲到了使用深度测试可以解决隐藏面消除的问题。并且效果看起来很完美,但是深度测试真的就没有一点问题吗?...

  • OpenGL之多边形偏移、裁剪测试、颜色混合

    上一篇我们分析了深度测试可以一次性解决隐藏面消除和深度的问题,但是它也带来了潜在风险——Z-fighting (Z...

  • OpenGL-深度测试

    本节了解的内容 什么叫做深度缓冲区。 深度缓冲区的作用。 如何使用深度缓冲区测试。 可视化深度值。 如何解决深度值...

  • OpenGL-深度测试

    通过本文你可以了解到的 什么是深度? 什么是深度缓缓冲区? 如何使用深度测试? 什么是可视化深度值? 深度值相同如...

  • 九、OpenGL渲染技巧 - 深度测试&多边形偏移&裁剪&混合

    1. 深度测试 深度测试的目的是防止被其他面遮挡的面显示出来。开启深度测试后,会对新的片段进行测试,测试通过的片段...

  • OpenGL隐藏面消除详解

    什么是隐藏面消除? 隐藏面消除:在绘制3D场景的时候,我们需要决定哪些部分是对观察者可见的,或者哪些部分是对观察者...

  • 03、OpenGL隐藏面消除

    在渲染过程中可能产生的问题 在绘制3D场景的时候,我们需要决定哪些部分是对观察者可见的,或者哪些部分是对观察者不可...

  • OpenGL-⑨-深度缓冲区和深度测试

    深度是什么? 深度就是该像素点在3D世界中距离摄像机的距离,Z值。 深度缓冲区(Depth-Buffer) 深度缓...

网友评论

    本文标题:OpenGL-消除隐藏面之深度测试

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