美文网首页
OpenGL--正背面剔除

OpenGL--正背面剔除

作者: 源本平凡 | 来源:发表于2020-07-09 23:56 被阅读0次

1. 背景

  • 在绘制3D场景时,为了尽可能的逼真,需要有远小近大的效果,而且可能会出现互相遮盖的情况。我们需要决定哪些部分对观察者是可见的,或者说哪些部分对观察者不可见,对于不可见的部分,我们应该及早的丢弃,例如在一个不透明的墙壁后的物体就不应该渲染。这种问题称之为隐藏面消除(Hidden surface elimination),或者称之为找出可见面(Visible surface detemination)。例如下图所示,正面的正方体会遮住后面的一部分,这种情况下为了提高渲染性能我们就不应该渲染被遮住的那部分,那如何处理呢?
    正方体.jpg

2. 解决方案

2.1 油画算法

解决上述问题,其中一种简单的办法就是油画算法(painter’s algorithm)

  • 思路:油画算法的基本思路是,先绘制场景中离观察者较远的物体,再绘制较近的物体。例如绘制下面图中的物体先绘制红色部分,再绘制黄色,最后绘制灰色部分,即可解决隐藏面消除问题。
    油画算法1.png
  • 弊端:使用油画算法时,只要将场景中物体按照离观察者的距离远近排序,由远及近的绘制即可。但是使用油画算法也是有弊端的,那就是当下图三个三角形进行叠加时,油画算法将无法处理。


    油画算法2.png

2.2 正背面剔除

当我们观察场景中对象时,一般只能以一定角度来观察,那么对象的某些面我们是看不到的,例如你观察一个立方体,最多只能同时看到3个面,有时只能看到1个面,而我们绘制时如果不采取剔除背面的措施,则要绘制6个面,其中包括一些我们根本看不到的面。对于立方体这个面较少的几何对象,性能开销不明显,但是对于复杂的模型,开启背面剔除则能明显改善渲染性能。 背面剔除,就是早点丢弃对观察者来说是背面的片元的一种方法。

使用方式

上面提到,要早点丢弃对观察者来说是背面的片元,那么现在的问题是如何确定哪个面是背面的问题? OpenGL中使用顶点绕序(winding order)来确定。所谓绕序就是当几何对象细分为三角形时,三角形顶点相对于中心的定义顺序,具体如下图所示:

顶点绕序.png
左边的图中指定顶点的顺序是顺时针的,右边是逆时针的。
以三角面指向观察者的方向为大拇指指向,其余手指逆时针绕着大拇指,如果手指的绕向和三角面顶点绕向一致,则这个面为正面,否则为背面。

需要注意的是,三角形的正面还是背面,这个是根据观察者的观察方向而变动的。例如下面的图中:

观察方向.png
左侧的三角形顶点顺序为1->2->3,右侧的三角形顶点顺序为1->2->3。当观察者在右侧时,则右边的三角形方向为逆时针方向为正面,而左侧的三角形为顺时针则为背面;当观察者转到左侧时,左侧的三角形为逆时针绕序判定为正面,而右侧的三角形为顺时针绕序判定为背面。可以看出正面和背面是由三角形的顶点定义顺序和观察者的观察方向共同决定的,而且随着观察方向的改变,正面和背面将会跟着改变。
//用于修改正面的函数
void glFrontFace(GLenum mode);

//mode有两种:GL_CW(顺时针),GL_CCW(逆时针),
//OpenGL中的默认值:GL_CCW

正背面剔除技巧主要涉及三个方法

  • 开启正背面剔除
//开启表面剔除 (默认背面剔除)
void glEnable(GL_CULL_FACE);
  • 关闭正背面剔除
//关闭表面剔除(默认背面剔除)
void glDisable(GL_CULL_FACE);
  • 设置需要剔除的面
void glCullFace(GLenum mode);

//mode有两种:GL_FRONT(剔除正面), GL_BACK(剔除背面,是默认值), GL_FRONT_AND_BACK(剔除正背面)

首先我们来对比下使用背面剔除和未使用背面剔除时,穿过甜甜圈内部,我们看到的景象。下图是没有开启背面剔除时:


未剔除.png

可以看到,穿过内部时,看到了甜甜圈后面的部分。
当开启了背面剔除时,穿过内部时,看不到甜甜圈的背面:


已剔除.png
注意点

在使用背面剔除时需要注意,在指定物体表面的顶点时,顶点的顺序需要定义为正向的逆时针顺序。启用背面剔除一般而言总能改善渲染性能,但是具体是否开启背面剔除还是要根据应用场景而定。当渲染某些非封闭类型几何对象,例如一颗草的模型时,则不需要开启背面剔除。

相关文章

  • OpenGL--正背面剔除

    1. 背景 在绘制3D场景时,为了尽可能的逼真,需要有远小近大的效果,而且可能会出现互相遮盖的情况。我们需要决定哪...

  • OpenGL--深度测试、多边形偏移以及颜色混合原理解析

    一、深度测试 1.1 深度测试解决什么问题 由前一篇OpenGL--如何使用正背面剔除解决问题博客,我们知道,我们...

  • OpenGL--如何使用正背面剔除解决问题

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

  • OpenGL深度测试

    在上一篇OpenGL正背面剔除中提到了正背面剔除的弊端:如果前后两个点都是正面或是背面,这时OpenGL无法区分哪...

  • OpenGL 渲染技巧之深度测试

    在上篇的 正背面剔除的文章中我们使用正背面剔除的的方式解决了甜甜圈正背面显示错乱的问题,但是呢同时引出了新的问题,...

  • OpenGL正背面剔除

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

  • OpenGL 正背面剔除

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

  • OpenGL: 正背面剔除

    案例分析 1.用平面着色器绘制一个环并旋转, 效果如下: 一切看似没有问题. 2.再用光源着色器绘制一个立体环并旋...

  • OpenGL正背面剔除

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

  • OpenGL 正背面剔除

    OpenGL 在绘制三维立体图形时, 如果不做处理, 就会产生一些不符合常理或者逻辑问题, 本次讲述正背面显示错...

网友评论

      本文标题:OpenGL--正背面剔除

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