美文网首页
OpenGL(八)-深度缓冲区带来的隐患以及预防方案

OpenGL(八)-深度缓冲区带来的隐患以及预防方案

作者: king_jensen | 来源:发表于2019-05-20 16:01 被阅读0次
    logo.jpg

    ZFighting闪烁问题的原因

    因为开启深度测试后,OpenGL 就不会再去绘制模型被遮挡的部分. 这样实现的显示更加真实.但是由于深度缓冲区精度的限制对于深度相差非常小的情况下.(例如在同一平⾯上进行2次 制),OpenGL 就可能出现不能正确判断两者的深度值,会导致深度测试的结果不可预测.显示出来的现象交错闪烁.


    583E8C6E3C09B77F9E95238AF514B822.png
    F313A48CBD3007088C42DD64387A18E4.png

    ZFighting闪烁问题问题解决

    第一步: 启⽤Polygon Offset 方式解决
    让深度值之间产生间隔.如果2个图形之间有间隔,是不是意味着就不会产⽣干涉.可以理解为在执⾏深度测试前将⽴方体的深度值做⼀些细微的增加.于是就能将重叠的2个图形深度值有所区分.

    启⽤用**Polygon Offset **⽅方式

     glEnable(GL_POLYGON_OFFSET_FILL)
    

    参数列表:
    GL_POLYGON_OFFSET_POINT 对应光栅化模式: GL_POINT
    GL_POLYGON_OFFSET_LINE 对应光栅化模式: GL_LINE
    GL_POLYGON_OFFSET_FILL 对应光栅化模式: GL_FILL’

    第二步: 指定偏移量量
    通过glPolygonOffset来指定glPolygonOffset需要2个参数: factor , units
    每个Fragment 的深度值都会增加如下所示的偏移量:
    Offset = ( m * factor ) + ( r * units);
    m : 多边形的深度的斜率的最⼤值,理解一个多边形越是与近裁剪面平⾏,m 就越接近于0.
    r : 能产⽣于窗口坐标系的深度值中可分辨的差异最小值.r 是由具体OpenGL 平台指定的一个常量.
    一个⼤于0的Offset 会把模型推到离你(摄像机)更远的位置,相应的一个⼩于0的Offset 会把模型拉近
    一般⽽言,只需要将-1.0 和 -1 这样简单赋值给glPolygonOffset 基本可以满足需求.

    void glPolygonOffset(Glfloat factor,Glfloat units);
    

    应⽤用到⽚片段上总偏移计算⽅方程式:
    Depth Offset = (DZ * factor) + (r * units);
    DZ:深度值(Z值)
    r:使得深度缓冲区产生变化的最⼩值
    负值,将使得z值距离我们更近,⽽正值,将使得z值距离我们更远.

    第三步: 关闭Polygon Offset

     glDisable(GL_POLYGON_OFFSET_FILL)
    

    ZFighting闪烁问题预防

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

    相关文章

      网友评论

          本文标题:OpenGL(八)-深度缓冲区带来的隐患以及预防方案

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