首先要了解OpenGL的图形管线有哪些内容,再分别去了解其中的相关的关系;
管线分别包括了顶点缓冲区/数组对象,定点着色器,纹理,片段着色器,变换反馈,图元装配,光栅化,逐片段操作,帧缓冲区。其中顶点着色器和片段着色器是管线的可编程阶段。
-
顶点着色器
其实现了顶点操作的通用可编程方法,其的输入包括了如下:着色器程序-描述顶点上执行操作的顶点着色器程序源代码或者可执行程序么,其实就是那个glsl的文件。
顶点着色器输入(或者属性)-用顶点数组提供的每个顶点的数据,应该是着色器程序语言中的那个attribute语句。
统一变量(uniform)-顶点(或者片段)着色器使用的不变数据。应该是使用了uniform的语句。
采样器-代表顶点着色器使用纹理的特殊统一变量类型。应该是使用了sample的语句。
有个注意的地方,在OpenGL ES 2.0中,顶点着色器的输出称作可变变量,也就是varying的语句,但是在3.0中改名为顶点着色器输出变量。
图元光栅化阶段,可以将每个生成的片段计算顶点着色器输出值并作为输出传递给片段着色器。在3.0中,增加一个新的功能,变换反馈,可以使顶点着色器的输出可以选择性的写入到一个输出缓冲区,而不一定会传送到片段着色器。
其中,统一变量uniform,存储组合的模型视图喝投影矩阵。顶点着色器的输入in,顶点着色器的输出out;
- 图元装配
顶点着色器之后,下一阶段就是图元装配,图元是三角形、直线或者精灵等几何对象,图元的每个顶点被发送到顶点着色器的不同拷贝。在图元装配期间,这些顶点被组合成图元。
对于每个图元,必须确定图元是否位于视锥体(屏幕上可见的3D空间区域)内,如果图元没有完全在视锥体之内,则可能需要进行裁剪,如果图元完全在该区域之外,它就会被抛弃,裁剪之后,顶点位置被转换成屏幕坐标,或者进行一次淘汰操作,根据图元面向前方或者后方来抛弃它们。接下来就可以进入到管线的下一阶段-光栅化阶段。
- 光栅化
此时,绘制的图元仍是点精灵或者直线或者三角形精灵等等。其实光栅化就是将这些图元转化成一组二维片段的过程,每个片段的输出包括了屏幕坐标,颜色等属性和纹理坐标等。然后,这些片段由片段着色器来处理。
- 片段着色器
在光栅化阶段对于每个图元生成的每个片段都会去执行这个片段着色器的程序。采用如下的输入:
着色器程序,描述片段上所执行操作的片段着色器源代码或者可执行程序。
输入变量,光栅化单元用插值为每个片段生成的顶点着色器输出,也就是顶点着色器中的输出值作为其的输入变量。
统一变量,片段(或者顶点)着色器使用的不变数据。
采样器,代表片段着色器所用纹理的特殊统一变量类型。
片段着色器可以抛弃片段,也可以生成一个或者多个颜色值作为输出。一般来说,除了渲染到多重渲染之外,片段着色器只输出一个颜色值,在多重渲染目标的情况下,为每个渲染目标输出一个颜色值。光栅化阶段生成的颜色、深度、模版和屏幕坐标位置变成管线逐片段的输入。
注意的是,顶点着色器必须输出和片段着色器读入的同一组变量。
- 逐片段操作
其中,逐片段的操作包括很多的操作,包括了
片段数据,像素归属测试,裁剪测试,模版测试,深度测试,混合,抖动。
其中片段的数据也就是执行了片段着色器的操作后的数据。
像素归宿测试,确定帧缓冲区中位置的像素目前是不是归OpenGL es所有。这个测试能够使窗口系统能够控制帧缓冲区中的哪些像素属于当前OpenGL es的上下文。比如一个显示OpenGL es帧缓冲区窗口的窗口被另一个窗口所遮蔽,则窗口系统可以确定被遮蔽的像素不属于OpenGL es上下文,从而完全不显示这些像素,这个由OpenGL es内部进行,不受人的控制。
裁剪测试,确定是否位于作为OpenGL es状态的一部分的裁剪矩形范围内。
模版和深度测试,这些测试将在输入片段的模版和深度值上进行,以确定片段是否应该被拒绝。
混合,将新生成的片段颜色值和保存在帧缓冲区位置的颜色值结合起来。
抖动,可用于最小化,因为使用有限精度在帧缓冲区中保存颜色值而产生的伪像。