发现一遍极为适合理解渲染管线的流程,觉得完全适合自己思路理解。尤其是图解很详细。就引用了过来。同时调整了文章布局,加了些其他解析。
一、 概述
当前OpenGL的版本为3.3,基于可渲染管线,实现模型生成,渲染,图像输出等工作。可渲染管线就是把三维顶点经过一系列加工变成二维的离散的像素点。
并且用户可以在特定着色阶段自由配置(如在顶点着色和片段着色阶段,这也是和固定流水线最大的不同)。

二、 详细流程
上图所示基本上是正确的,但不太直观,一个三维顶点怎么变换成像素的呢?
我把它分为两大步:
- 先把三维顶点二维化
- 把二维顶点离散化(像素化)将2D坐标转换为实际的有颜色的像素
2.1. 三维顶点二维化
2.1.1 模型顶点构建
模型顶点都是相对模型自己的坐标构建的,即物体坐标。只能表达模型的形状,无法得到它的位置和姿态,这就必须引入世界坐标。

2.1.2 变换到世界坐标
世界坐标表达一个更大的坐标域,模型的每个顶点都可以由世界坐标表达出来,由物体坐标到世界坐标,需乘以一个世界矩阵,这样就得到了相对世界坐标的模型。

2.1.3 世界坐标变换为相机坐标
世界坐标变换相机坐标,由物体坐标到世界坐标,需乘以一个观察矩阵,这样就得到了相对于相机坐标的模型。

2.1.4 相机坐标构建视锥体
相机坐标变换屏幕坐标。任何三维模式都是以二维形式(屏幕)显示的。所以三维模型通常要转化为二维。首先要以相机为原点构建视锥体。

2.1.5 相机坐标变换为屏幕坐标
接下来模型的三维坐标就要变换到二维坐标了,需乘以透视矩阵,最终得到了一个投影于视锥体近平面的二维模型。

2.2. 二维顶点像素化
经过透视投影得到的顶点是线性的,无法显示在屏幕上,还需要进行像素化,如下图:

顶点数据是一系列顶点的集合。以下为一系列操作阶段
2.2.1 顶点着色器
把一个单独的顶点作为输入。【意味着,如果有很多顶点会执行很多次】
主要目的:把3D坐标转换为另一中3D坐标,同时顶点着色器允许我们对顶点属性进行一些基本处理。
2.2.2 图元装配
将顶点着色器输出的所有顶点作为输入,并将所有的点装饰城指定图元的形状。
2.2.3 几何着色器
产生新的顶点,构造出新的(或者其他的)图元来生成其他形状。
2.2.4 光栅化
将图元映射为最终屏幕上相应的像素,生成供片段着色器(Frament Shader)使用的片段(Fragment)。在片段着色器运行之前会执行裁切(Cliping)。
裁切会丢弃超出视图以外的所有像素,用来提升执行效率。
2.2.5 片段着色器
计算一个像素的最终颜色,这也是所有OpenGL高级效果产生的地方。
通常,片段着色器包含3D场景的数据,比如(光照,阴影,光的颜色等等),这些数据可以被用来计算最终的像素的颜色。
2.2.6 混合测试
检查片段对应的深度(和模板(Stencil))值,用它们来判断这个像素是其他物体的后面还是前面,决定是否应该丢弃。
这个阶段也会检查alpha值,并对物体进行混合(Blend)。
所以,即使在片段着色器中计算出来了一个像素输出颜色,在渲染多个三角形的时候,最后的像素颜色也可能完全不同。
附:着色器的理解
图形管线可以划分为几个阶段,每个阶段将会把前一个阶段输出作为输入。所有这些阶段都是高度专门化(都有特定函数),并且容易并行执行。
正是由于它们具有并行执行的特性,当今大多数显卡都有成千上万的小处理核心,它们在GPU上为每一个(渲染管线)阶段运行各自的小程序,从而在图形渲染管线中快速处理你的数据。而这些小程序就叫做着色器(shader)。
参考资料: