Chapter2 渲染流水线
一、渲染流水线的概念
1.目标
- 将三维场景转换为二维图像的过程
2.阶段划分——应用阶段、几何阶段、光栅化阶段
①应用阶段
- 负责方:CPU——开发者在这个阶段拥用绝对的控制权
- 主要任务:
- 准备场景数据:摄像机、视锥体、场景中的模型、光源等
- 剔除不可见的物体:通过粗粒度剔除(culling)技术,将那些不可见的物体剔除出去,提高渲染效率
- 设置渲染状态:材质、shader、纹理等,定义场景中物体的渲染方式
- 输出: 渲染图元 (rendering primitives),例如点、线、三角面等
②几何阶段
- 决定需要绘制的图元是什么,在哪里绘制,怎么绘制
- 这个阶段可以进一步分成更小的流水线
- 负责方:GPU
- 主要任务:
- 处理渲染图元:逐项点、逐多边形处理渲染图元
- 顶点变换: 将顶点坐标从模型空间转换到屏幕空间,为光栅化做准备
- 顶点着色:根据材质和光照等信息,计算顶点的颜色
- 输出: 屏幕空间的二维顶点坐标、每个顶点对应的深度值、着色信息等
③光栅化阶段
- 负责方:GPU
- 主要任务:
- 生成像素: 确定每个渲染图元覆盖的像素,并生成片元 (fragment)
- 插值: 对顶点信息进行插值,得到每个片元的颜色、法线、纹理坐标等状态
- 片元着色: 根据片元信息,计算每个像素的最终颜色
- 逐片元操作: 执行深度测试、模板测试、混合等操作,将片元颜色写入颜色缓冲区
- 输出: 最终渲染的图像
二、CPU和GPU的通信
- 渲染流水线的起点是CPU,应用阶段可以分为以下三个方面
- 把数据加载到显存中
- 设置渲染状态
- 调用Draw Call
1.数据加载
- 渲染所需的所有数据(如网格、纹理等)都从硬盘加载到系统内存(RAM),然后再由 CPU 将这些数据加载到 GPU 的**显存(VRAM)**中
- 显存是 GPU 的专用存储空间,GPU 可以快速访问这些数据
2.设置渲染状态
- CPU 需要设置渲染状态,以告诉 GPU 如何渲染场景中的网格
3.调用Draw Call
- 定义:Draw Call 是 CPU 调用图像编程接口(如 OpenGL 或 DirectX)发出的命令,它告诉 GPU 开始渲染的图元对象
- 作用:GPU 会根据渲染状态和输入的顶点数据来进行渲染计算
- 影响:
- 大量物体需要渲染 → \rightarrow → 大量的 Draw Call
- Draw Call 本身不会造成性能问题,真正影响性能的是 CPU。CPU 需要为每个 Draw Call 准备数据,并检查渲染状态,这些操作会消耗 CPU 资源
- 减少开销:可以采用批处理技术,将多个网格合并成一个更大的网格,然后在单个 Draw Call 中渲染它们
三、GPU渲染流水线
图形渲染管线与GPU渲染流水线的关系
- GPU渲染流水线
- 是指在GPU硬件实现,负责将顶点数据、纹理数据等渲染所需要的信息转化为最终像素颜色
- 取决于硬件GPU设计
- 图形渲染管线
- 图形渲染管线是指整个渲染流程,包括了GPU渲染流水线,也包含了CPU应用阶段
- 取决于图形API(OpenGL、DirectX等)
- 深色为可编程阶段;浅色为可配置但不可编程阶段;第二深的为固定函数不可配置不可编程阶段
主要流水线
①顶点着色器
- 是流水线第一阶段,对每个顶点进行处理,但得不到顶点之间的关系
- 输入来自于CPU
- 主要功能
-
坐标变换:将顶点坐标从模型空间转换到齐次裁剪空间,并进行透视除法后,最终得到归一化的设备坐标(NDC)
-
逐顶点光照:计算顶点光照信息
-
输出数据:将计算得到的数据传给后续阶段
-
②裁剪Clipping
- 将不在摄像机视野范围内的图元裁剪掉
③屏幕映射
- 将图元坐标从三维空间转换到二维屏幕坐标系中(投影),对z坐标不做任何变换
- 值会被传输到光栅化阶段
④三角形设置 —— 进入光栅化阶段
- 计算光栅化三角形所需的信息,例如三角形边界的表示方式(上一个阶段得到的是三角形网格的顶点)
⑤三角形遍历
- 判断三角形网格的像素覆盖情况,并且生成片元
- 使用顶点信息进行插值
⑥片元着色器
- 是流水线的最后一个可编程阶段,它对每个片元进行处理
- 主要任务:
- 纹理采样:从纹理中获得像素信息
- 光照计算:计算片元光照信息
- 颜色输出:输出片元的最终颜色值
⑦逐片元操作
- 对每个片元进行深度测试、模板测试和混合操作,最终将片元颜色写入颜色缓冲区
- 深度测试用于判断片元的可见性
- 模板测试用于限制渲染区域
- 混合操作用于处理半透明物体