写在前面 
在绘制封闭类型的几何对象时,开启背面剔除功能能够提高渲染性能。本节简要介绍下背面剔除,示例程序可以在我的github下载

什么是背面剔除

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

背面剔除的使用

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

左边的图中指定顶点的顺序是顺时针的,右边是逆时针的。

以三角面指向观察者的方向为大拇指指向,其余手指逆时针绕着大拇指,如果手指的绕向和三角面顶点绕向一致,则这个面为正面,否则为背面。

在OpenGL中,我们指定逆时针和顺时针的三角形顶点如下:

   GLfloat vertices[] = {
// Clockwise
vertices[0], // vertex 1
vertices[1], // vertex 2
vertices[2], // vertex 3
// Counter-clockwise
vertices[0], // vertex 1
vertices[2], // vertex 3
vertices[1] // vertex 2
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

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

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

在OpenGL中开启背面剔除需要使用:

   glEnable(GL_CULL_FACE);
  • 1

同时OpenGL提供了函数glCullFace来供用户选择剔除哪个面:

API void glCullFace(GLenum mode); 
mode参数为 GL_FRONT, GL_BACK, GL_FRONT_AND_BACK 3个枚举类型。默认为GL_BACK.

以及glFrontFace函数用来根据绕序指定哪个为正面:

API void glFrontFace(GLenum mode); 
mode参数为GL_CW ,GL_CCW。默认值是GL_CCW。

如果要剔除正面,代码:

    glCullFace(GL_BACK);
glFrontFace(GL_CW);
  • 1
  • 2

和下面的代码等价:

   glCullFace(GL_FRONT);
  • 1

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

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

当我们剔除正面时,观察者的位置,决定了哪是正面,当观察者处于立方体正面时,剔除正面看到效果:

当观察者移动到可以看到立方体三个面时,判定正面,顶面和右侧面为正面,则剔除正面后的效果为:

最后的说明

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

版权声明:使用署名-非商业性使用CC协议[http://creativecommons.org/licenses/by-nc/3.0/deed.zh] https://blog.csdn.net/ziyuanxiazai123/article/details/52267314

OpenGL学习脚印:背面剔除(Face Culling)的更多相关文章

  1. OpenGL学习脚印:深度測试(depth testing)

    写在前面 上一节我们使用AssImp载入了3d模型,效果已经令人激动了.可是绘制效率和场景真实感还存在不足,接下来我们还是要保持耐心,继续学习一些高级主题,等学完后面的高级主题,我们再次来改进我们载入 ...

  2. OpenGL学习脚印: uniform blocks在着色器中的使用 转自https://blog.csdn.net/wangdingqiaoit/article/details/52717963

    写在前面 目前,我们在着色器中要传递多个uniform变量时,总是使用多个uniform,然后在主程序中设置这些变量的值:同时如果要在多个shader之间共享变量,例如投影矩阵projection和视 ...

  3. Qt OpenGL:学习现代3D图形编程之四,透视投影浅析

    一.非真实的世界 与之前几篇文章不同的是,这里要画12个三角形,这个12个三角形构造一个方形棱柱(这里为长方体).棱柱的每个四边形表面由两个三角形组成.这两个三角形其中的一条边重合,而且它们的六个顶点 ...

  4. OPENGL——背面剔除

    Opengl 表面剔除是提高 Opengl 程序渲染效率的一个有效途径. 我们知道,OpenGL 渲染的基本单位是一个个的三角形面片.无论多么复杂的3D 模 型都是由一个个基本的三角型的面片组成的. ...

  5. OpenGL 背面剔除

    在OpenGL种可使用glEnable(GL_CULL_FACE)开启背面剔除功能,即把那些我们看不见的面删除.但在剔除之前我们需要定义正面和背面,这个可以用法线来理解.在数学学科中,法线是用右手法则 ...

  6. OpenGL学习进程(11)第八课:颜色绘制的详解

        本节是OpenGL学习的第八个课时,下面将详细介绍OpenGL的颜色模式,颜色混合以及抗锯齿.     (1)颜色模式: OpenGL支持两种颜色模式:一种是RGBA,一种是颜色索引模式. R ...

  7. OpenGL学习进程(8)第六课:点、边和图形(三)绘制图形

    本节是OpenGL学习的第六个课时,下面介绍OpenGL图形的相关知识:     (1)多边形的概念: 多边形是由多条线段首尾相连而形成的闭合区域.OpenGL规定,一个多边形必须是一个“凸多边形”. ...

  8. OpenGL学习进程(10)第七课:四边形绘制与动画基础

        本节是OpenGL学习的第七个课时,下面以四边形为例介绍绘制OpenGL动画的相关知识:     (1)绘制几种不同的四边形: 1)四边形(GL_QUADS) OpenGL的GL_QUADS图 ...

  9. OpenGL学习进程(9)在3D空间的绘制实例

        本节将演示在3D空间中绘制图形的几个简单实例:     (1)在3D空间内绘制圆锥体: #include <GL/glut.h> #include <math.h> # ...

随机推荐

  1. Logging模块总结 2018/5/30

    日志的级别 Level 用处 数字级别 DEBUG 详细的信息,在调试过程中用于诊断错误 10 INFO 用于确认事件正在运行 20 WARNING 意外发生时予以提醒,或者预测一些未来可能发生的一些 ...

  2. nginx 多域名配置,采用多配置文件的方式

    nginx 中多域名配置,目前采用多配置文件的方式. 配置过程比较简单. 首先在 nginx 目录下创建子目录 vhosts . 在 vhosts 目录中创建对应域名的配置文件.如有域名 898hi. ...

  3. nginx源码完全注释(1)ngx_alloc.h / ngx_alloc.c

    首先看 ngx_alloc.h 文件,主要声明或宏定义了 ngx_alloc,ngx_calloc,ngx_memalign,ngx_free. /* * Copyright (C) Igor Sys ...

  4. 一款比较好用的JS时间控件-laydate

      官方讲解:http://laydate.layui.com/ 具体的内容请看官方讲解,此处仅说名应用: 1.在jsp或html或其他中引入laydate.js <script src=&qu ...

  5. mongodb修改用户名密码

    首先先将启动mongo的配置文件里面的 auth:用户认证,改为false. 正确做法,利用db.changeUserPassword db.changeUserPassword('tank2','t ...

  6. Windows Server 2012 R2 Standard x64 deploy Visual Studio 2015 Application

    When I run the Server application on Windows Server 2012 R2 operation system. I meet the error:MSVCP ...

  7. [SoapUI] 获取Cookie,并循环遍历当前Project下所有的Test Suite,Test Case,Test Step,将Cookie传递给这些Test Step

    import com.eviware.soapui.support.types.StringToStringMap //Get all th cookies in the response , her ...

  8. Java 前台后台数据传递、中文乱码解决方法

    1.向前台传递数据;2.向后台传递数据;3.ajax post 提交数据到服务端时中文乱码解决方法;4.数组类型参数传递; 1.向前台传递数据:1.1 字符串数据传递:  这种方式只是单一的向前台传递 ...

  9. Android开发adb环境配置

    adb的全称为Android Debug Bridge,就是起到调试桥的作用. 在命令行cmd中打开adb,如果Android开发的环境配置有误,会出现如下错误提示: 解决方法,右键我的电脑-> ...

  10. RabbitMQ的四种ExChange

    在message到达Exchange后,Exchange会根据route规则进入对应的Queue中,message可能进入一个Queue也可能进入对应多个Queue,至于进入哪个Queue或者是说哪个 ...