1. pipeline
1.1 顶点着色器
顶点着色器实现了顶点操作的通用可编程方法。顶点着色器可以实现基于顶点的传统操作,如通过矩阵来变换顶点位置、计算照明公式生成逐顶点颜色、生成或者变换纹理坐标等。
1.1.1 输入
顶点着色器的输入包括:
- 着色器程序(shader program):描述顶点上执行操作的顶点着色器程序源代码或可执行文件。
- 顶点属性(vertex atrribute):使用顶点数组提供的每个顶点的属性。
- 统一变量(uniform):顶点着色器中使用的不变的数据。
- 采样器(sampler):使用纹理时的特殊的unform变量,可用于纹理采样。
1.1.2 输出
顶点着色器的输出:又称为varying变量,在图元光栅化阶段,会为每个片段计算顶点着色器的输出,并将其作为输入传递给片段着色器。 顶点着色器的顶点输出,实际上是在裁剪坐标系内
1.1.3 MVP矩阵
Model Matrix 模型矩阵:用于变换物体对象,将物体坐标从模型空间(相对于物体原点)转换到世界空(相对于世界原点,全局唯一)中。
View Matrix 视图矩阵/观察矩阵:它定义了相机在世界坐标系中的位置和观察方向,将物体顶点从世界空间转换至观察空间(相对于相机)。
ModelView矩阵都是线性变换(包括齐次坐标的平移操作),一般几何属性,如法线,光照等的计算,都在经过此变换后的观察空间中进行。
Projection Matrix 投影矩阵:投影矩阵是为了模拟人眼看待世界的“近大远小”透视效果,或正交投影效果。它将顶点从观察空间,转换至裁剪空间。
裁剪空间的坐标是所指定的齐次坐标,裁剪空间中的坐标范围是 , ,,其归一化后的坐标会限制在一个视景体内。
1.2 图元装配
1.2.1 图元组装
根据用户的opengl绘制调用命令(如 glDrawArrays或 glDrawElements)和指定的图元类型(如 三角形GL_TRIANGLES、连续线段GL_LINE_STRIP等),管线将连续的顶点数据“连接”成具体的形状。组装好的图元仍然位于裁剪空间
1.2.2 裁剪
裁剪发生在裁剪空间,目的是丢弃那些完全不在视锥体内的图元,以及对部分位于视锥体内的图元进行裁剪,只保留可见部分(可能会生成多的点)。 裁剪必须在裁剪空间中进行,因为如果到NDC中的映射是非线性的,如要新加点和属性,则会不对。(非线性,如裁剪空间平行线映射后在NDC中会相交,「铁轨」)
1.2.3 透视除法
裁剪完后,会进行透视除法,对于裁剪坐标中的每个分量,都除以分量。则有 ,顶点坐标经过透视除法,从裁剪空间转换至归一化的设备坐标NDC空间,其表示范围在一个标准的立方体内:。顶点的分量被保留,需要用于透视矫正插值。
1.2.4 视口变化
NDC 坐标被变换到窗口坐标(也称为屏幕坐标)。这个变换可以通过 glViewport和 glDepthRange函数定义的参数控制。此时z坐标也会变换到视锥体的far和near两个平面范围间,记录到zbuffer里面。
1.2.5 背面剔除
剔除背向摄像机的三角形。
1.3 光栅化
光栅化是将图元转换为一组二维片元的过程。(片元区别于像素,可能会被后面的测试丢弃或修改)。光栅化发生在视口变换后,此时有片元顶点的窗口坐标,z坐标。
1.3.1 确定片元
确定哪些片元被图元覆盖,如通过重心坐标系来来判断像素中心点是否在三角形内。
1.3.2 片元属性插值
利用重心坐标来平滑地计算三角形内部任意一点的属性值。它会根据三个顶点的属性值,按比例进行混合。(重心坐标是,基于窗口坐标系下的像素位置计算得到)
1.4 片段着色器
片段着色器为片元操作实现了通用的可编程方法。光栅化阶段中生成的每一个片元,都会执行该着色器程序。
1.4.1 输入
片段着色器的输入:
- 着色器程序(shader program):描述片段上所执行的片段着色器程序的源代码或可执行文件。
- 输入可变变量(varying):光栅化阶段为每个片段插值生成的顶点着色器的输出。
- 统一变量(uniform):片段着色器中使用的不变的数据。
- 采样器(sampler):使用纹理时的特殊的unform变量,可用于纹理采样。
1.4.2 输出
片段着色器可以抛弃片元(discard关键字),或者生成一个或多个颜色值作为输出(framebuffer + 多个attachments + drawbuffers)
1.5 逐片段操作
- 像素归属测试:确定帧缓存中像素目前是否归当前OpenGL ES上下文所有,确认是否可以不显示这些像素,如OpenGL ES窗口被另外一个窗口所覆盖,则可以完全不显示这些像素。这些实在OpenGL 内部控制,不由开发人员管理。
- 裁剪测试scissor test,允许定义一个屏幕空间的二维矩形区域,只有该范围内的可以写入帧缓存,之外的会被丢弃。
- 模版测试stencil test,允许定义一个特定的模版mask,来检测片元是否写入还是丢弃。相比裁剪测试,可以定义更高级的图案类型。
- 深度测试depth test,解决3D场景中物体的可见性(遮挡关系),根据深度值对片元颜色进行覆盖。
- 混合Blend :将源片元的颜色与帧缓冲区中目标像素的颜色进行组合,常用于绘制透明物体。