前向渲染与延迟渲染
要知道前向渲染与延迟渲染的概念和区别, 先要搞清楚渲染管线的基本概念
渲染管线
1. 世界矩阵 World Matrix
已知一个物体的正向(Foreward)方向, 上向(Up)方向, 右向(Right)方向和位置(Position), 我们可以通过这三个方向和一个坐标构建一个世界矩阵(World Matrix)
\[\begin{bmatrix} Foreward.x & Foreward.y & Foreward.z & 0 \\ Up.x & Up.y & Up.z & 0 \\ Right.x & Right.y & Right.z & 0 \\ Position.x & Position.y & Position.z & 1 \end{bmatrix}\]在3D图形学中: 表示方向的齐次位置是0, 表示位置的齐次位置是1
- 方向向量不具有空间中的绝对位置, 只表示方向, 因此不参与平移变换, 通过将齐次坐标的最后一位设为0, 确保在矩阵乘法中不会受到平移部分的影响
- 位置向量代表的是空间中的一个点。通过将齐次坐标的最后一位设为1,确保该点能够被平移
作用: 世界矩阵可以将物体从模型空间(Model Space)变换到世界空间(World Space)
2. 透视投影矩阵 Perspective Projection Matrix
作用: 把视锥体映射到单位立方体(即 -1 到 1 的立方体), 再映射到屏幕空间
步骤
- 在近平面上的点 z_near, 它们的 x,y 坐标几乎不变, 其他平面上的点 x 和 y 坐标会随着距离的增加(z 变远)而线性缩小: 类似将视锥体压成一个长方体
- 变换z坐标,映射到 [-1, 1] 范围内,用于深度缓冲的计算: 类似将长方体压缩成一个立方体
转换形式
- 对点(x, y, z, 1)进行透视投影变换, 得到(x’, y’, z’, w’)
- 齐次坐标归一化: (x’/w’, y’/w’, z’/w’)
3. 渲染管线
顶点输入: 将几何数据输入 (可编程)顶点着色器: 将几何数据进行顶点处理(MVP变换等) 图元装配: 封装成点, 线, 三角形等图元 (可配置)几何着色器: 对图元进行二次处理(扩展多个三角形等) 光栅化: 将图元转换为像素(片元), 确定覆盖像素范围 (可编程)片元着色器: 计算颜色(blinn-phong等) 像素操作: 对像素进行混合, 测试等(深度测试, 丢弃被挡住的三角) 帧缓冲输出: 写入缓冲区, 交换链等
4. 如何将一个点渲染到屏幕上
将一个点通过World Matrix变换到世界空间, 再通过View Matrix变换到相机空间, 再通过Projection Matrix变换到裁剪空间, 最后通过Viewport变换到屏幕空间
以上变换之后, 经过图元装配, 光栅化, 片元着色器等步骤, 最终将一个点渲染到屏幕上, 渲染出的一帧画面会被输出到一个Buffer(帧缓冲区)中, 之后再输出到屏幕上
5. 如何渲染纹理
Mipmap: 为了解决纹理贴图时的锯齿或摩尔纹问题, 采用Mipmap技术, 生成一系列不同分辨率的纹理, 在渲染时根据纹理与屏幕的距离选择合适的Mipmap纹理
6. 如何处理光照
光线向物体表面发射, 通过blinn-phong模型或lambert模型等计算光照, 通过光照计算得到的颜色值, 与纹理颜色值进行混合, 最终得到物体表面的颜色
前向渲染与延迟渲染
1. 前向渲染
对场景中的每个物体进行逐个的渲染, 将他们的颜色光照和阴影等效果计算出来, 再将叠加的结果写入帧缓冲区并输出到屏幕上
- 通过顶点着色器将物体的顶点变换屏幕空间
- 通过片元着色器对每个像素进行处理, 计算其颜色和光照
- 将处理后的像素写入帧缓冲区
优点: 实现简单, 适用于场景物体数量较少, 能够处理透明物体和复杂的光照效果
缺点: 每个物体都需要进行完整的渲染过程, 对于大场景和复杂的光照计算, 前向渲染的性能可能会受到限制
2. 延迟渲染
为了解决前向渲染的性能问题, 出现了延迟渲染技术:
将渲染过程分为多个阶段, 以提高渲染效率和图形质量
前向渲染
- 几何处理, 光栅化, 片元着色器等都在同一个管线中完成, 处理复杂场景的时候会产生大量片元, 导致性能下降
延迟渲染
- 将几何处理和光栅化分开, 将几何信息和光照信息分别存储在不同的缓冲区中, 几何处理阶段只负责计算顶点位置和法线信息, 并将这些信息存储在几何缓冲区中, 光栅化阶段只负责完成片元位置和纹理坐标等信息, 并将这些信息存储在片元缓冲区中
- 在几何处理和光栅化阶段之后, 延迟渲染会执行一个光照处理阶段, 该阶段会根据几何缓冲区和片元缓冲区中的信息计算光照效果, 由于光照只需要对可见的片元进行计算, 因此可以大大减少需要计算的片元数量, 提高渲染效率
3. 前向渲染与延迟渲染的结合及在引擎中的应用
延迟渲染的优点: 处理很多光源或没有透明物体的场景时, 延迟渲染的性能优势明显
前向渲染的优点: 处理透明物体和复杂的光照效果时, 前向渲染的效果更好, 抗锯齿效果更好
处理透明与不透明物体的方法:
- 在CPU中储存两个Buffer, 一个储存透明/半透明物体, 一个储存不透明物体
- 不透明Buffer使用延迟渲染, 透明/半透明Buffer使用前向渲染
- 将两个Buffer合并输出到屏幕上
处理光照的方法:
- 使用延迟渲染处理主要的光照
- 使用前向渲染处理复杂的光照效果(如全局光照, 阴影等)