从OpenGL ES 2.0开始就已经告别了固定管线,之后就实现了可编程的图形管线,下面这张图是OpenGL ES 2.0的渲染流程:
固定管线 VS 可编程管线
其中灰色的部分是顶点着色器
和片段着色器
,是可以编程的部分。在之前的固定管线的时代,顶点的变化只能是可选的状态的改变,功能比较有限,也无法进行扩展,比如我们渲染一个光照下面的球,渲染的样式可能是下面这样的:
而可编程管线来渲染,由程序来定义,可以执行自定义计算,功能比较强大,扩展性比较强,能根据程序渲染出特别逼真的效果:
顶点着色器
顶点着色器是用来处理顶点的,它的输入和输出系统如下:
图元装配
图元 (Primitive) 在OpenGL ES 中就是基本的绘图对象,三角形
、直线
和点
,注意OpenGL ES中不能绘制多边形
。图元的每个顶点来自顶点着色器的不同拷贝,在 图元装配
期间,这些顶点被组合成图元。
对于每个图元,必须确定每个图元是否位于屏幕上可见的3D空间区域内,如果没有完全在,则需要进行裁剪
,如果图元完全不在可视区域,就会被抛弃
,裁剪和淘汰之后,顶点位置转换成屏幕坐标,这时图元就会准备下一个阶段---光栅化
光栅化
光栅化用来将图元映射到像素设备,比如屏幕或者离线framebuffer,确定用多少像素表示图元对象,经过光栅化之后,会有锯齿。
下图是将一个三角形图元,经过光栅化之后:
光栅化将图元转化成一组
二维片段
,然后这些二维片段由着色器处理,这些二维片段代表着可以在屏幕上绘制的像素。每个片段的输出,屏幕坐标(x, y)、颜色、纹理坐标等属性。
片段着色器
片段着色器为光栅化之后的片段上的操作实现了可编程。
片段着色器可以抛弃片段,也可以生成一个或者多个颜色值作为输出,输出最终的像素颜色
逐片段操作
在片段着色器之后,下一阶段是逐片段操作。光栅化生成的屏幕坐标为(x, y)的片段只能修改帧缓冲区中位置为(x, y)的像素
- 像素归属测试:这个测试用于确定帧缓冲区中的位置(x, y)的像素目前是不是归OpenGL ES所有。例如,如果一个显示OpenGL ES帧缓冲区窗口的窗口被另一个窗口所遮蔽,则窗口系统可以确定被遮蔽的像素不属于OpenGL ES上下文,从而完全不显示这些像素。像素归属测试是OpenGL ES 的一部分,但是不由自主开发人员来确定,在内部进行。
- 裁剪测试:把坐标(x, y)的像素如果超出OpenGL ES的裁剪范围,就会被抛弃。
-
模版测试:对输入
Fragment Data
的模版值
进行测试,看这个是否应该拒绝 -
深度测试:对输入
Fragment Data
的深度值
进行测试,比如3D中的远近效果,查看Frame Buffer
中的数据和当前数据的深度进行比较,远的丢掉,近的保留 -
混合:将输入
Fragment Data
中的颜色值 和 保存在Frame Buffer
中的颜色值,进行混合 - 抖动:用于因为使用有限的精度值在帧缓冲中保存颜色而产生的伪像
在经过逐片段操作之后,片段要么被拒绝,要么在帧缓冲区Frame Buffer的(x, y )的位置写入片段的颜色
、深度
或者模版
。如果启动了相应的掩码,可以更精确的控制写入,比如,设置颜色缓冲区写入掩码,任何红色的颜色值都不被写入颜色缓冲区。