从0开始的OpenGL学习(二十一)-背面剔除

本章主要解决一个问题:

如何使用背面剔除来减少需要绘制的三角形数量?

引言

背面剔除,顾名思义,就是在渲染的时候,将背对着观察者的面片丢弃,只将正面朝向观察者(观察者能看到的)面片进行计算。举个栗子:之前我们显示的立方体盒子,不管从哪个角度看,我们最多只能看到3个面,有时甚至都只能看到一个面,那么,为什么我们还要对其他看不见的面进行渲染计算呢?将看不见的面剔除,我们最少可以节省50%的CPU和GPU资源。

背面剔除的目的就是节省CPU和GPU的资源,千万别觉得现在的CPU和GPU资源已经过剩了,对游戏来说,还差的远了。

如何判断一个面片是正面还是背面?

这是我们面临的最直接的一个问题。我们采用的方法是:定义一个顶点绕序来标识成正面,这样,OpenGL在渲染的时候如果看到这个面的顶点绕序不是正面绕序,那就判定其实背面,把它丢弃。

顶点绕序有两种:顺时针和逆时针。如下图,左边的就是顺时针绕序,右边的就是逆时针绕序:


顶点绕序

原理十分简单!当我们在定义顶点的时候,我们可以在顶点1之后先定义顶点3来改变三角形的顶点绕序。用代码模拟就是这个样子:

float vertices[] = {
    // 顺时针
    vertices[0], // 顶点1
    vertices[1], // 顶点2
    vertices[2], // 顶点3
    // 逆时针
    vertices[0], // 顶点1
    vertices[2], // 顶点2
    vertices[1]  // 顶点3 
};

每个三角形图元的三个顶点都构成了一个顶点绕序。在渲染的时候,OpenGL会用这些信息来判断这是正面还是背面。默认情况下,顶点是逆时针顺序的会被认为是正面。

在我们上一章的代码中使用glEnable(GL_CULL_FACE)开启背面剔除,你会发现正面看窗户是可以看到的,背面看窗户就看不到了。分析transparentVertices顶点数组之后你就可以明白这顶点绕序是怎么回事了。

从这里就可以看出,当我们定义顶点的时候,还需要考虑其顺序问题。当所有的顶点都被正确定义后(立方体背面的顶点需要顺时针定义),我们观察立方体的时候就会是这样子:


观察示意图

我们可以看到的三角形是逆时针绕序,会被渲染。后面的三角形是顺时针绕序,会被丢弃。而当我们转过去的时候,后面的三角形又会变成逆时针绕序,前面的会变成顺时针绕序,这正是我们想要的!

如何使用背面剔除

细心的你肯定已经发现,我们已经尝试过使用背面剔除功能了。没错,就是使用一脉相承的glEnable函数,传入的参数是GL_CULL_FACE。在启用背面剔除之前,我们先要确保立方体的顶点绕序是逆时针的。很遗憾,之前我们一直用的立方体顶点绕序不全都是逆时针绕序的。你可以在这里获得一份逆时针绕序的顶点数据。

快使用这份顶点数据,然后开启背面剔除看看效果。笔者看到的效果是这样的:


显示效果

从背面看过去就很明显可以看出背面剔除已经启用,因为我们看不到那些窗户了。还有很明显的地方就是地板不见了,因为我们现在看到的也是地板的背面,如果将调整视角从下往上看就可以看到地板了。

这样就够了吗?当然不是。OpenGL还提供了一些控制背面剔除效果的函数,甚至连前面也可以剔除掉。调用glCullFace(GL_FRONT);就可以剔除正面。效果是这样:


正面剔除效果

可以作为glCullFace参数的选项有:GL_FRONT,GL_BACK和GL_FRONT_AND_BACK。各个参数使用效果都能从参数名字上看出来,这里不再多说了。

要注意,剔除功能只影响多边形,而对点和直线无影响。例如,使用glCullFace(GL_FRONT_AND_BACK)后,所有的多边形都将被剔除,所以看见的就只有点和直线。

还有一个函数:glFrontFace()。用来设置哪个面是正面。默认参数为GL_CCW表示逆时针为正面,你也可以设置成GL_CW表示顺时针为正面。一般我们不需要去修改它。

处于研究的目的,我们将顺时针设置成正面,剔除背面,看看会有什么效果:


设置顺时针方向为正面的效果

和前面的效果一样,这就对了。由于本文代码比较简单,不单独提供代码下载了,大家在前面的代码上修改就好了。

总结

这么简单,有啥好总结的,就是一个顶点绕序,一个glEnable,一个glCullFace,一个glFrontFace而已。不过千万别小看背面剔除,所有的游戏都会使用到,尤其是大型游戏中。想想看,精细人物模型面片数在1万以上,电影级别的面片数10万以上,你说背面剔除不重要,呵呵?

下一篇
目录
上一篇

参考资料

www.learnopengl.com(非常好的一个网站,建议学习)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342