《Real-Time Rendering》第四版学习笔记——Chapter 2 The Graphics Rendering Pipeline
引言
渲染管线的核心作用是在基于一组虚拟相机、三维物体以及光源系统等条件下输出一个二维图像。
由它们的几何特性和环境特性以及相机在环境中的位置决定物体在图像中的位置与形状;而物体外表则由材质属性、光源特性和纹理等共同决定。
一、渲染管线整体结构
实时渲染管线在大体上可以分为四个主要步骤:
- 应用阶段
- 几何处理阶段
- 光栅化
- 像素处理
每个步骤都包括了多个子步骤。这些属于功能性逻辑划分的阶段,在实际实现架构中可能会整合某些阶段进行优化处理。

- 由应用程序自身触发的应用流程将通过CPU执行相应的逻辑操作。
- 几何处理阶段负责完成物体的变换与投影操作,并涉及其他几何相关计算。
- 这一阶段需确定哪些图形元素需要呈现以及其呈现方式和位置。
- 通常会运行在GPU上以提高计算效率。
- 光栅化过程识别位于三角形内部的像素并将其传递给后续处理环节。
- 最终执行的是逐像素渲染流程。
- 每个像素将被详细着色,并根据深度信息判断其可见性及参与颜色混合。
- 几何处理阶段负责完成物体的变换与投影操作,并涉及其他几何相关计算。
二、 应用阶段
该阶段通常在CPU上运行,所以开发者可以完全控制该阶段。
应用阶段的核心任务是在该阶段结束后传输到几何处理阶段
由于采用了软件实现方式, 因此这一阶段不会分割成各个子阶段. 然而, 可以借助多核技术来提高计算效率.
碰撞检测通常会完成这一过程;此外,在这一阶段还负责处理来自外部的各种输入(如键盘、鼠标等设备);另外一种优化方法可以在这一阶段完成。
三、几何处理
几何处理阶段运行在GPU上,主要负责大部分单三角形和单顶点的操作。
该阶段可以分为四个子阶段:顶点着色、投影、裁剪和屏幕映射。

3.1 顶点着色
顶点着色主要有两个任务:
- 计算顶点位置;
- 评估顶点输出哪些数据,如法线、纹理坐标等。
Vertex shaders are responsible for performing per-vertex operations, including applying illumination calculations to position and normal vectors, and only record the color values for each vertex. These shaders are typically utilized in data assembly steps that handle vertex attributes, and their processing typically skips the full rendering equation.
模型转换(model transform):每个具体的几何体对象都与一个特定的转换矩阵相关联。通过这种转换能够确定该物体在三维空间中的位置和朝向。此外,在某些情况下也会有某个特定的几何体映射到多个不同的参数空间中。
通过这种方式能够生成一系列位于不同位置、尺寸各异的几何体样本,并且这种机制能够有效减少重复计算。
该变换操作是为了将相机置于坐标原点,并使其对准;并使z轴负方向朝向相机观察方向的同时使y+轴正方向朝上而x+轴正方向向右。
投影转换操作(projection transformation):将被转换的体积限定在单位立方体范围内。
其中最常见的两种类型是正交投影与透视投影。
3.2 可选顶点处理
细分着色(tessellation shading)主要指通过将物体表面划分为微小单元来进行颜色计算;几何着色(geometry shading)则是根据物体的几何特性来决定颜色分布;流输出(stream output)则用于实时数据传输以保证渲染流畅性)。这些可选处理步骤受制于GPU硬件能力和是否有必要执行。
其目的是为了生成适当的三角形数量以表示出曲面上的细节特征。一个曲面上的区域是由多个顶点围成的区域,在进行细分后会得到一个更大的顶点集合,并且场景相机可以根据各个区域所处的距离来进行相应的三角形数量调整。
其目的是为了生成适当的三角形数量以表示出曲面上的细节特征。一个曲面上的区域是由多个顶点围成的区域,在进行细分后会得到一个更大的顶点集合,并且场景相机可以根据各个区域所处的距离来进行相应的三角形数量调整。
几何着色器与细分着色器在功能上具有相似特性,在实际应用中都能处理各种类型的几何元素并新增顶点;然而相比之下几何着色器更为简单其主要原因是生成顶点的方式局限于局部区域而不会影响整体效果;此外所生成的几何元素类型也会受到更多的限制因此在某些特定场景下运行效率更高
通过流水线设计使GPU能够执行几何运算。在常规流程中,这些顶点信息会被依次传递至下一个阶段进行进一步处理,并最终呈现于屏幕上。此外,在某些情况下,几何计算的结果可以通过特定接口输出至工作区数组,并供CPU或其他组件直接访问。这些数据不仅可以直接供CPU调用,在后续的渲染指令序列中也能够持续利用。
这三个步骤按照细分——几何着色——流输出的顺序执行。
3.3 裁剪
只有当一个图形元素整体或其部分位于视图范围内时才会被传递到光栅化阶段;如果图形元素完全位于视图范围之外则不会被传递;而裁剪操作仅作用于那些位于视图范围内的图形元素。
3.4 屏幕映射
在进入屏幕映射阶段的过程中,我们使用的依然是三维坐标的系统。在此过程中,每个图形元素(图元)在其自身的\mathit x和\mathit y坐标的值会被转换至屏幕上对应的显示位置。为了确定最终在屏幕上呈现的位置信息,则需要结合屏幕坐标的数值与\mathit z坐标的深度信息来计算出最终的位置参数。由于不同图形渲染接口(API)对显示效果的要求可能存在差异,在实际应用中可能会采用不同的窗口坐标系来适应各种需求
窗口坐标和重新映射的\mathit z坐标传递到光栅化步骤。
四、光栅化
当基于变换与投影的顶点及其对应的渲染数据给定时,在此之后我们的目标则是确定位于所有待渲染图形元素内部的所有像素。这一过程可划分为两项关键步骤:图形元素装配以及三角形遍历。
rasterization will transfer 2D vertices, associated depth values, and other color information to pixels on the screen.
判断三角形是否覆盖了某个像素,这取决于如何建立GPU管线。
4.1 图元装配
在这个步骤中,将计算出三角形的差分、边界方程以及其他相关数据。这些数据将被用来进行三角形遍历,并同时用于数据插值。该阶段主要依赖于固定功能硬件。
4.2 三角形遍历
三角形遍历是指确定哪些像素位于给定三角形内部的过程。每个三角形片段的属性是通过基于三个顶点的空间插值方法获取的。这些属性包含以下内容:一是像素位置对应的深度信息;二是通过几何变换计算得到的各种着色数据。
所有在图元内部的像素将会传递到像素处理步骤。
五、像素处理
在图像处理过程中, pixels经过两步骤:着色与合成。此阶段对每个 pixel执行计算与操作过程。
5.1 像素着色
该阶段的输出结果是一个或多个颜色值,并传输给下一个步骤。该阶段由可编程的GPU核执行运算流程。开发者提供一个包含所有计算过程的像素着色器程序,在OpenGL中被称作片段着色器。
该阶段至少需要为每个像素输出一个颜色值。
5.2 合成
合成阶段的主要任务是整合来自像素着色阶段生成的缓存区中的片段颜色数据
该阶段是不可编程的,但是是高度可配置的。
在这一阶段中也承担了提升可见性的责任。此外,在这一部分不仅包含了深度测试的要求还涉及到了半透明物体绘制的具体流程。
缓存结构临时存储已绘制元素的位置,并用于决定是否允许将渲染数据记录在颜色缓存以及深度缓存中。
以上所有的功能统称为混合操作(blend operation)。
帧缓冲通常会包含以上所有的缓冲。
