音视频从入门到放弃

OpenGL--- (四)OpenGL渲染技巧:正背面剔除

2020-08-07  本文已影响0人  阿木小丸子

一、什么是正背面剔除?

正背面剔除方案,是OpenGL中针对图形绘制的一种技巧,主要用于处理立体图形绘制时,只绘制观察者能看到的部分,看不到的部分就丢弃不绘制,这种做法可以将渲染性能提高50%左右。

二、我们为什么需要正背面剔除?

例:我们需要绘制一个甜甜圈(甜甜圈是OpenGL中提供的模型,直接使用即可),整体的绘制流程如下: 1.png

其中RenderScene函数如下:


2.png

甜甜圈旋转时,会出现以下情况:

3.png

在绘制3D场景的时候,我们需要决定哪些部分是对观察者可见的,或者哪些部分是对观察者不可见的,对于不可见的部分,应该及早丢弃。例如在一面不透明的墙壁后面,就不应该渲染,这种情况叫做“隐藏面消除”。

三、详解正背面剔除?

背景:

一个3D图形,从任何一个位置和方向上看,最多可以看到3个面。
如果我们不绘制看不到的几个面,丢弃这几个面的数据,OpenGL在渲染的性能即可提高超高50%。
任何平面都有两个面,正面和背面,意味着一个时刻只能看见一个面。
OpenGL可以做到检查所有正面朝向观察者的面,并渲染它们,从而丢弃背面朝向的面。这样可以节约片元着色器的性能。
通过顶点数据的顺序,告诉OpenGL当前绘制的图形哪个是正面(按照逆时针顶点连接顺序的三角形面132),哪个是背面(按照顺时针顶点连接顺序的三角形面123),如下图三角形。
正面和北面由三角形的顶点定义顺序和观察者方向共同决定的,随着观察者的角度和方向的改变,正面背面也会跟着改变。


1.png

解决方案:分析立方体中的正背面

甜甜圈正背面剔除(在原流程上修改):

(1)main函数中新增右击菜单栏相关函数:

glutCreateMenu(ProcessMenu);
glutAddMenuEntry("Toggle depth test",1);
glutAddMenuEntry("Toggle cull backface",2);
glutAddMenuEntry("Set Fill Mode", 3);
glutAddMenuEntry("Set Line Mode", 4);
glutAddMenuEntry("Set Point Mode", 5);
glutAttachMenu(GLUT_RIGHT_BUTTON);

(2)新增ProcessMenu函数:
通过mainloop监听右键菜单触发的消息,收到点击触发消息后,回调该函数对相应菜单进行的点击操作。主要逻辑如图所示:


2.png

(3)在RenderScene函数中新增正背面剔除的开启/关闭操作。


3.png

//开启/关闭正背面剔除功能
if (iCull) {
glEnable(GL_CULL_FACE);
//以下两行是默认的,可以不写
glFrontFace(GL_CCW);
glCullFace(GL_BACK);
}else
{
glDisable(GL_CULL_FACE);
}

如上,甜甜圈的问题就基本解决了,但是。。。
甜甜圈又出现了新的问题,出现了一个新的问题。旋转时会看到一个缺口,针对这个问题,下一篇文章https://www.jianshu.com/p/f8419da4f64b 会详细讲解哦~

注: 如下是OpenGL的开放方法:

1、开启表面剔除(默认背面剔除)
void glEnable(GL_CULL_FACE);
2、关闭表面剔除(默认背面剔除)
void glDisable(GL_CULL_FACE);
3、用户选择剔除哪个面(正面/背面)
void glCullFace(GLenum mode);
mode参数为:GL_FRONT,GL_BACK,GL_FRONT_AND_BACK
4、用户指定绕序哪个为正面
void glFrontFace(GLenum mode);
mode参数为:GL_CW,GL_CCW
5、例如,剔除正面实现(1)
glCullFace(GL_BACK)
glFrontFace(GL_CW)
6、例如,剔除正面实现(2)
glCullFace(GL_FRONT)

上一篇 下一篇

猜你喜欢

热点阅读