渲染管线的主要功能是在给定一个虚拟相机、三维物体、光源以及其他条件的基础上,生成一个二维的图像。
物体在图像中的位置和形状取决于它们的几何特征、环境特征和相机在环境的位置,而物体的外表则取决于材质属性、光源、纹理和着色方程。
实时渲染管线在大体上可以分为四个主要步骤:
每个步骤都包含了若干个子步骤。这里的步骤是功能逻辑上的分割,在实际的实现结构中,有可能会将其中部分步骤合在一起执行。
该阶段通常在CPU上运行,所以开发者可以完全控制该阶段。
应用阶段最重要的任务是,在该阶段的末尾,将需要渲染的几何信息被传递给几何处理阶段。
因为是基于软件实现,所以该阶段不会分成各个子阶段,不过可以利用CPU的多核特性来提升性能。
碰撞检测通常在该阶段实现;该阶段也负责接收来自其他来源的输入,如键盘鼠标等;还有加速算法可以在该阶段实现。
几何处理阶段运行在GPU上,主要负责大部分单三角形和单顶点的操作。
顶点着色主要有两个任务:
顶点着色器(vertex shader):通常情况下,对物体的着色操作会对每个顶点的位置和法线应用光照;仅存储顶点的颜色结果。通常用于顶点相关的数据装配,一般不会执行渲染方程。
模型变换(model transform):每个模型都与一个模型变换相对应,这个变换决定了这个模型的位置和方向。也有可能一个模型会对应到多个模型变换,这样可以生成多个不同位置的不同大小的模型实例,并且避免了多次复制几何体。
视图变换(view transform):该变换是为了将相机置于原点,并对准;并且使其看向 z \mathit z z轴的负方向,使 y \mathit y y轴正方向指向上, x \mathit x x轴正方向指向右。
投影变换(projection transform):将试图体积变换为一个单位立方体,坐标都限制在 ( − 1 , − 1 , − 1 ) (-1,-1,-1) (−1,−1,−1)和 ( 1 , 1 , 1 ) (1,1,1) (1,1,1)之间。有两种常用的投影变换,正交投影和透视投影。
细分着色(tessellation shading)、几何着色(geometry shading)和流输出(stream output)。这些可选处理步骤依赖于GPU硬件能力以及是否必要。
曲面细分是为了产生合适的三角形数量来表示曲面。曲面可以表示为一系列由顶点组成的面片,曲面细分可以将这些面片顶点转换为更大的顶点集合,场景相机可以根据面片远近来决定三角形的数量。
几何着色器与细分着色器类似,处理各种图元并且产生新的顶点;但是与细分着色器相比更简单,因为顶点的生成限制在局域,并且输出的图元类型也更受限制。
流输出可以使GPU成为几何引擎。通常情况下,经过处理的顶点数据会被传递给下一个步骤处理直到渲染到屏幕,但是也可以将几何处理的结果输出到数组中。这个数据可以提供给CPU使用或者在后续的渲染指令中继续使用。
这三个步骤按照细分——几何着色——流输出的顺序执行。
只有一个图元的整体或部分在视图体内才会传递到光栅化步骤。整体在视图体内的图元,会原封不动的传递到下个阶段;完全不在视图体内的图元,则不会传递;而裁剪只会在那些部分在视图体内的图元上执行。
裁剪阶段4维齐次坐标,第四个值的作用是为了在透视投影的时候能够正确的进行三角形插值和裁剪。
当进入屏幕映射阶段时,坐标系仍然是三维的。其中每个图元的 x \mathit x x坐标和 y \mathit y y坐标会转换到屏幕的坐标系。屏幕坐标和 z \mathit z z坐标一起组成了窗口坐标系。不同的图形API会有不同的窗口坐标系。
窗口坐标和重新映射的 z \mathit z z坐标传递到光栅化步骤。
当经过变换和投影的顶点与其相应的渲染数据给定后,下一个目标就是找到所有在需要渲染的图元内部的像素。这个步骤可以分为两个子步骤:图元装配和三角形遍历。
光栅化将在屏幕空间的二维顶点,及其对应的深度值和其他着色信息,转化到屏幕上的像素。
判断三角形是否覆盖了某个像素,这取决于如何建立GPU管线。
这个步骤中,会计算三角形的差分、边界方程以及其他的数据。这些数据会用于三角形遍历,以及数据插值。该阶段使用的是固定功能硬件。
三角形遍历指的是查找那些像素在一个三角形内的过程。每个三角形片段的属性是通过三个顶点进行插值得到的。这些属性包括片段的深度,以及几何处理步骤得到的各种着色数据。
所有在图元内部的像素将会传递到像素处理步骤。
像素处理步骤分为两个子步骤:像素着色和合成。该阶段针对单个像素计算和操作。
该阶段的输出结果时一个或多个颜色值,并传递到下一个步骤。该阶段运行在可编程的GPU核上。开发者提供一个包含所有计算过程的像素着色器程序(在OpenGL中称为片段着色器)。
该阶段至少需要为每个像素输出一个颜色值。
合成阶段的任务是将像素着色阶段产生的存储于缓存区的片段颜色进行融合。
该阶段是不可编程的,但是是高度可配置的。
该阶段也负责解决可见性。这里涉及到深度测试,以及半透明物体的绘制顺序。
模版缓冲存储已绘制的图元位置,用于控制是否能够将渲染数据写入到颜色缓冲和深度缓冲中。
以上所有的功能统称为混合操作(blend operation)。
帧缓冲通常会包含以上所有的缓冲。