美文网首页
OpenGL 基础渲染(深度测试)

OpenGL 基础渲染(深度测试)

作者: _涼城 | 来源:发表于2020-07-20 11:38 被阅读0次
OpenGL 基础渲染(正背面剔除) - 简书

在上文案例使用了正背面剔除后,出现了新的问题。如下图所示,那我们要如何解决这个问题呢。这个问题出现的原因是,无法区分那个图层在前,OpenGL 提供了另外一种高效消除隐藏面的技术,它叫做深度测试

正背面剔除后.png
深度测试
深度

在绘制一个像素A时,有一个Z值表示它到观察者的距离,这个值其实就是深度

当另外一个像素B需要在屏幕上的同样位置绘制时,新像素B将与已经存储的像素A的Z值进行比较。如果新像素B相对观察者更近,则覆盖原像素点A。

深度缓冲区

在OpenGL内部,这个任务是通过深度缓冲区实现的,它在显存中存储了屏幕上每个像素的深度值。深度缓冲区默认值是1.0,表示最大的深度值。深度值的范围是[0,1]之间。

  • 申请深度缓冲区

    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
    
  • 清空深度缓冲区(恢复默认1.0)

    glClear(GL_DEPTH_BIT)
    
深度测试操作
  • 开启深度测试

    glEnable(GL_DEPTH_TEST)
    
  • 关闭深度测试

    glDisable(GL_DEPTH_TEST)
    
深度测试解决隐藏面
  • 监听右键弹出菜单

     glutCreateMenu(ProcessMenu);
    
  • 在弹出菜单回调中,设置是否开启深度测试

    ProcessMenu

     //右键菜单栏选项
     void ProcessMenu(int value)
     {
        switch(value)
        {
            case 1:
                iDepth = !iDepth;
                break;
        }
        glutPostRedisplay();
     }
    
  • 在重塑函数中,判断开启深度测试

    setupRC

      //根据设置iDepth标记来判断是否开启深度测试
      if(iDepth)
          glEnable(GL_DEPTH_TEST);
      else
          glDisable(GL_DEPTH_TEST);
    
  • 下图为开启深度测试后的效果

    深度测试后.png
z-fighting

虽然深度测试解决渲染问题并提供性能。但是当两个几何图形绘制到同一位置时,会导致渲染冲突。这种情况通常称为z-fighting(Z冲突)。

多边形偏移

OpenGL 提供了一个glPolygonOffset模式使得我们可以调节片段的深度值,使得深度值产生偏移而不实际改变3D空间中的物理位置,从而解决z-fighting的情况。

  • 启用多边形偏移(填充几何图形)

    glEnable(GL_POLYGON_OFFSET_FILL)
    
  • 启用多边形偏移(填充点)

    glEnable(GL_POLYGON_OFFSET_POINT)
    
  • 启用多边形偏移(填充线)

    glEnable(GL_POLYGON_OFFSET_LINE)
    
  • 指定偏移量

    void glPolygonOffset(GLfloat factor, GLfloat units);
    
  • 关闭多边形偏移

    glDisable(GL_POLYGON_OFFSET_FILL)
    

    应用到片段上的总偏移可以通过下面的方程式表示。其中DZ是深度值相对于多边形屏幕区域的变换量,r则是使深度缓冲区产生变换的最小值。

Depath Offset = (DZ * factor) + (r * units)

相关文章

网友评论

      本文标题:OpenGL 基础渲染(深度测试)

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