一、面剔除
对于一个3D立方体,无论我们从哪个方向,最多只能同时看到3个面。如果我们能够以某种方式丢弃另外几个看不见的面,我们就能省下超过50%的片段着色器执行数!
这正是面剔除(Face Culling)所做的。OpenGL能够检查所有面向(Front Facing)观察者的面,并渲染它们,而丢弃那些背向(Back Facing)的面,节省我们很多的片段着色器调用(它们的开销很大!)。我们可以设置顶点数据的环绕顺序(Winding Order),来告诉OpenGL哪些面是正向面(Front Face),哪些面是背向面(Back Face)。
二、环绕顺序
当我们定义一组三角形顶点时,我们既可以用顺时针(Clockwise),也可以用逆时针(Counter-clockwise)的环绕顺序来定义它们。
OpenGL在渲染图元的时候将使用这个环绕顺序来决定一个三角形是一个正向三角形还是背向三角形。默认情况下,逆时针顶点所定义的三角形将会被处理为正向三角形。
当我们定义顶点顺序的时候,我们应该想象对应的三角形是面向我们的,所以我们定义的三角形从正面看去应该是逆时针的。实际的环绕顺序是在光栅化阶段进行的,也就是顶点着色器运行之后。这些顶点就是从观察者视角所见的了。
观察者所面向的所有三角形顶点就是我们所指定的正确环绕顺序了,而立方体另一面的三角形顶点则是以相反的环绕顺序所渲染的。这样的结果就是,我们所面向的三角形将会是正向三角形,而背面的三角形则是背向三角形。下面这张图显示了这个效果:
启用面剔除:
glEnable(GL_CULL_FACE);
从这一句代码之后,所有背向面都将被丢弃。目前我们在渲染片段的时候能够节省50%以上的性能,但注意这只对像立方体这样的封闭形状有效。当我们想要绘制上一节中的草时,我们必须要再次禁用面剔除,因为它们的正向面和背向面都应该是可见的。
我们可以调用 glCullFace 来决定剔除正向面还是背向面:
glCullFace(GL_FRONT);
glCullFace函数有三个可用的选项:
GL_BACK
:只剔除背向面(默认)。GL_FRONT
:只剔除正向面。GL_FRONT_AND_BACK
:剔除正向面和背向面。
我们也可以调用 glFrontFace 来选择顺时针的面还是逆时针的面作为正向面:
glFrontFace(GL_CCW);
觉得有帮助的话,打赏一下呗。。