OpenGL渲染管线漫谈

如果把OpenGL看做一个加工机器,它的功能就是把一系列顶点纹理数据可以在屏幕上面显示的像素。这就如同面条机器把一定比例的面和水加工成一根根面条一样。面条机器可以设置面条的宽度和厚度,这可以影响整个加工的面条,就相当于OpenGL可以设置纹理过滤模式,混合模式等全局状态,可以影响到这一帧的像素输出。从glDrawElements开始,OpenGL流水线就开始运作了,它由一系列过程串联而成,其中有些是程序可以操作的,比如顶点片段着色器;有些戏系统根据设置的全局OpenGL状态自动作用的,比如纹理采样和光栅化。

顶点着色:

这个过程完全由程序掌握,它可以使用所有传人的attribute和uniform变量。一般attribute变量包括位置,颜色,纹理,法线,uniform包括变换矩阵,灯光位置。输出包括变换后的顶点位置,通过视图投影变换,把位置变换为0~1之间,如果不再这个范围内,这个点在后面的剪切过程中剪切剔除掉,并由其它新生成的点代替。很多情况下也会包括纹理坐标,某些情况也会计算顶点的光照颜色。这些输出除了位置都是作为varying变量传递到下一个管线。

细分着色和集合着色:

顶点着色输出的是各个顶点数据,这两个过程会对顶点进行更进一步处理,比如创建更多图元。这两个过程在游戏中很少用到。所以一般可从顶点着色直接跳到下一步。

图元装配:

前面都是对顶点的处理,这里会把前面的顶点重新组装称为图元,比如一个个三角形。组装的原则是根据glDrawElements设置的参数,比如GL_TRIANGLES。

剪切:

在顶点着色中生成的顶点位置如果不再0~1之间,在这里会被剪切掉,通过剪切掉不必要的图元,会显著降低后面流程的工作量。这个部分完全由gl操作。

光栅化:

上面所有步骤输出的结果是一个个多边形,而最终显示的是一个个像素区域。这一步所做的就是把多边形通过插值生成一个个片段,即候选像素。除了位置,还有顶点着色输出的varying类型都会被插值,一般包括纹理坐标,法线坐标。

片段着色:

这一步计算光栅化之后每个片段的对应颜色和深度值,这是完全可编程的,也可以根据判断丢弃本片段。

剪切测试:

如果片段在glScissor范围之外,则直接丢弃。本过程完全由OpenGL处理。

模板测试:

可以用来实现倒影镂空等特效。测试失败则根据设置修改输出帧缓冲的模板值,然后丢弃;否则进行下面的深度测试。本过程完全由OpenGL处理。

深度测试:

如果失败则只根据设置修改模板值,然后丢弃。否则修改模板深度缓存并进行到下一步。本过程完全由OpenGL处理。

alpha混合:

混合前面计算的像素颜色和当前缓存的颜色,可用于半透明效果。本过程完全由OpenGL处理。

后面还有抖动和逻辑操作处理,但是对于一般游戏开发来说,alpha混合之后,就相当于得到显示到屏幕的颜色了。

这个流程完全是串行处理的,要降低后面的计算量,就要尽可能在更前面的步骤剔除掉不会最终显示的图元片段。程序可以操作的地方有两个。一个是在进入OpenGL管线之前,尽可能通过场景管理剔除掉不需要的图元;另一个是采用由近及远的画法,在深度测试中丢弃不会显示的片段。可以看到场景管理尤其重要,好的场景算法可以大大降低显卡的负担。

 

posted on 2017-07-24 00:26  zhangshuliai  阅读(167)  评论(0编辑  收藏  举报