在现代 GPU 架构下,渲染管线的演进本质上是 “权衡顶点处理(Draw Call / 几何提交)、片元算力(ALU)与显存带宽(Bandwidth)三者关系” 的历史。
1. 前向渲染 (Forward Rendering)
最符合直觉的”逐物体计算”架构,是所有管线的基准。
运行机制:
1 | |
- 性能复杂度:
( 为物体数, 为光源数)。多光源场景通常需要 Multi-pass 叠加,导致 Draw Call 数量暴增。
优势:
- 材质极度灵活: 每个物体独立着色,不受统一数据结构约束,可实现任意 Shading Model(各向异性、次表面散射、卡通渲染等)。
- 原生硬件 MSAA: 片元着色器独立运行,兼容光栅化阶段的多重采样。
- 天然支持半透明: 不需要额外的 Forward Pass,按深度排序后直接 Alpha Blend。
- 低显存占用: 无需 G-Buffer,适合移动端和低显存平台(如 Quest、Switch)。
劣势:
- 严重的光照 Overdraw: 被遮挡像素仍会执行完整的光照计算(无 Early-Z 优化时尤为严重)。
- 多光源扩展性极差: 10 个动态光源 × 1000 个物体 = 10000 次着色调用。
- Shader 变体爆炸: 不同光源数量组合需要预编译大量 Shader Variant(Unity URP 的
_ADDITIONAL_LIGHTSkeyword 即为此设计)。
工程实践补充(Unity URP):
- URP 默认使用 Forward Rendering,每个物体最多支持 8 盏 Additional Lights(可通过
AdditionalLightCountPerObject调整)。 Depth Priming功能本质是在 Forward 管线中插入一个 Depth Pre-pass,以剔除被遮挡像素的 ALU 浪费。- 在大世界场景中,Forward 通常与 GPU Instancing + DrawMeshInstancedIndirect 结合,将 Draw Call 压力转移到 GPU 端。
2. 延迟渲染 (Deferred Shading)
核心思想:空间换时间 —— 用 G-Buffer 显存换取光照计算与几何复杂度的解耦。
为了解决 Forward 中海量光源带来的 Overdraw 和复杂度问题,是现代 3A 引擎的基石。
运行机制:
1 | |
Geometry Pass: 渲染所有不透明物体,将 PBR 材质属性写入多渲染目标(MRT)构成的 G-Buffer。
Buffer 典型内容 精度 RT0 Albedo (RGB) + AO (A) RGBA8 RT1 World/View Normal (RGB) + Roughness (A) RGBA16F 或 RGBA8 RT2 Metallic + Specular + ShadingModel ID RGBA8 Depth 硬件深度缓冲 D24S8 或 D32 Lighting Pass: 在屏幕空间绘制光源几何体(Quad / 球体 / 锥体),采样 G-Buffer 计算光照并累加到 Accumulation Buffer。
- 性能复杂度:
( 为光源在屏幕上的像素覆盖面积),大幅优于 Forward 的 。
优势:
- 零光照 Overdraw: Geometry Pass 结束后只有最终可见像素参与光照计算。
- 海量动态光源: 光源计算与场景几何复杂度彻底解耦,理论上可支持数千盏光源。
- 后处理友好: 所有 G-Buffer 数据天然可用于 SSAO、SSR、SSGI 等屏幕空间后处理效果。
劣势:
- 显存与带宽黑洞: G-Buffer 的 MRT 读写极度消耗显存带宽(在 1080P 下,一帧完整的 G-Buffer 读写可高达数 GB/s)。在带宽受限的移动端 GPU(如 Mali、Adreno)上,这是致命问题,需结合 TBDR(Tile-Based Deferred Rendering)架构缓解。
- 材质同质化: 所有材质必须被编码进统一的 G-Buffer 结构,实现各向异性毛发、次表面散射等特殊 Shading Model 时,需要额外的 RT 或精心设计的编码方案(如用 ShadingModelID 区分 Shading Path)。
- 抗锯齿局限: G-Buffer 存储的是已插值的像素属性,无法使用硬件 MSAA(因为 MSAA 需要在着色前就完成多采样)。现代 Deferred 管线重度依赖 TAA 进行时间域反走样,但 TAA 会引入 Ghosting 和模糊问题。
- 半透明处理: Deferred 管线无法直接处理半透明物体,必须额外维护一个 Forward Pass(Deferred + Forward 混合管线)。
工程实践补充:
- Unreal Engine 的 Substrate 材质系统(UE 5.3+)是对传统 Deferred G-Buffer 材质同质化问题的系统性解答,通过可组合的材质层取代固定 G-Buffer 编码。
- Unity URP 目前的 Deferred Rendering Path 默认仅启用 4 个 RT(比 Built-in 的 Deferred 更保守),以控制带宽开销。
3. 延迟光照 (Light Pre-Pass / Deferred Lighting)
历史定位:折中方案 —— 诞生于早期主机时代,旨在解决 Deferred Shading 带宽受限的问题。
运行机制:
1 | |
- Geometry Pass 1: 渲染几何体,输出极”薄”的 G-Buffer(仅 Depth + Normal,带宽需求极低)。
- Lighting Pass: 遍历光源,利用 Depth 和 Normal 计算漫反射 + 高光信息,写入光照累加缓冲区(Light Accumulation Buffer)。
- Forward Pass: 再次渲染几何体,在片元着色器中读取自身材质(Albedo、Roughness 等)并采样光照缓冲区进行相乘融合,最终输出。
优势(对比 Deferred Shading):
- G-Buffer 极小(仅 2 个 RT),大幅降低带宽压力。
- 第二个 Forward Pass 中材质完全自由,恢复了任意 Shading Model 的支持。
- 支持硬件 MSAA(第二个 Pass 是标准 Forward 渲染)。
劣势(致命伤):双倍几何提交
所有不透明物体需提交两次(两个完整的顶点变换 + 光栅化流程)。在现代高多边形场景(数千万三角形)和高 Draw Call 场景下,顶点着色器压力和 CPU 提交开销远超带宽节省的收益。
Light Pre-Pass 的衰落时间线:
- Xbox 360 时代(2005-2010):带宽极度受限,此方案是主流。
- PS4/Xbox One 时代(2013+):GPU 带宽大幅提升,加之 Compute Shader 普及,Deferred Shading 和 Forward+ 逐渐取而代之。
- 目前此架构基本退出主流引擎,主要作为历史参考存在。
4. 分块与聚类渲染 (Tiled & Clustered Rendering)
核心思想:算力换效率 —— 将光源剔除逻辑从传统的 CPU/光源几何体提交转移到 GPU Compute Shader,通过空间数据结构实现精确的每像素/每体素光源列表。
这一层技术是正交于前三种架构的优化层,可以叠加在 Forward 或 Deferred 之上,形成 Forward+、Tiled Deferred、Clustered Forward、Clustered Deferred 等组合。
4.1 前向+ (Forward+ / Tiled Forward)
运行机制:
1 | |
- Depth Pre-pass: 预渲染场景,输出深度图(用于 Tile 的深度范围计算)。
- Light Culling (Compute): 将屏幕划分为均匀的 2D 网格(Tiles,通常 8×8 或 16×16 像素)。每个 Tile 由一组 GPU 线程处理,利用深度图计算该 Tile 的 Min/Max Depth,然后对每盏灯进行视锥体 vs AABB 相交测试,生成该 Tile 的局部光源索引列表,写入 Light Index Buffer。
- Forward Pass: 渲染几何体,片元着色器根据当前像素所在的 Tile 坐标查表,仅对该 Tile 的有效光源计算光照。
痛点:深度不连续(Depth Discontinuity)
Tile 在 Z 轴方向是一个从近裁面到远裁面的完整视锥体切片(长条形体积)。当同一个 Tile 内同时存在近处前景物体(如人物,depth ≈ 1m)和远处背景物体(如山脉,depth ≈ 500m)时,该 Tile 的 Min/Max Depth 跨度极大,导致大量远处光源被错误地分配给近处片元(反之亦然),光源列表虚假膨胀,ALU 浪费严重。
这是 Forward+ 在室内/外混合场景和包含大量深度变化场景中性能下降的根本原因。
4.2 聚类渲染 (Clustered Rendering)
Forward+ 的终极进化形态,彻底解决深度不连续问题。由 Ola Olsson 等人于 2012 年在 SIGGRAPH 上正式提出。
运行机制:
1 | |
3D 视锥体体素化(Cluster 构建):
- X/Y 轴:与 Tiled 相同,按屏幕像素网格划分。
- Z 轴(深度方向):按对数级(Exponential/Logarithmic)切片,使近裁面附近切片密集(精确),远处切片稀疏(高效)。典型划分为 16~32 层,最终形成数以千计(如 16×9×24 = 3456 个)的 3D Cluster。
- Cluster 无需每帧重建(视锥体不变时可复用),只需在相机参数变化时重新生成。
光源分配(Light Assignment, Compute):
- 对每个 Cluster 执行与每盏光源的 3D 空间相交测试(球体 vs AABB)。
- 将相交结果写入紧凑的 Light Index List 和 Cluster 查找表(Offset + Count)。
着色:
- 片元着色器根据当前片元的 View Space 坐标,解析其所属 Cluster(直接从 NDC/View 坐标计算,无需额外纹理采样)。
- 从查找表获取该 Cluster 的光源列表,仅对列表内光源计算光照。
优势:
极致的 ALU 优化: 每个片元只看与其所在 3D 体素相交的光源,Z 轴上的光照冗余被完全消除。
天然支持 Raymarching 体积渲染: 这是 Clustered Rendering 最重要的”隐性优势”之一——
在体积云(Volumetric Clouds)和体积雾的 Raymarch 步进中,采样点是 3D 空间中的任意位置,并不依附于任何几何表面,没有表面深度信息可用。传统 Forward/Tiled Forward 管线中,光源列表是以屏幕 Tile 为索引的,无法在 Raymarch 步进点处直接查询。而 Clustered 管线的光源数据结构本身就是 3D 视锥体空间的,Raymarch 步进点的 View Space 坐标可以直接解析出对应的 Cluster,从而获得精确的局部光源列表,与表面渲染复用同一套光照查询逻辑。
统一半透明/不透明管线: 半透明物体无需特殊处理,与不透明物体使用同一套 3D 空间查表逻辑,天然避免了 Deferred 管线中半透明的尴尬。
Compute 友好: Cluster 构建和光源分配完全在 GPU Compute Shader 中完成,与主渲染管线并行,CPU 侧压力极小。
劣势:
- Cluster 缓冲区显存开销: 需要维护 Cluster 查找表 + Light Index List,通常占用数 MB 显存(可接受)。
- Cluster 构建与光源分配的 Compute 开销: 在光源数量极多(数万盏)或 Cluster 划分极细时,Compute Pass 本身也会成为瓶颈。
- 着色器内的 Cluster 解析逻辑: 需要在 Shader 中内联 Cluster 坐标计算,对 Shader 代码有侵入性。
工程实践补充(Unity URP):
- Unity URP 在 Forward+ Rendering Path(Unity 2022 LTS+)中实装了 Clustered Light Culling,使用 Compute Shader 构建 3D Cluster,支持最多 256 盏 Additional Lights。
- 对于 GPU Driven Terrain +
DrawMeshInstancedIndirect的场景,Clustered 管线的优势尤为显著:地形像素通常深度跨度极大(山谷近地表 vs 远处天际),Clustered 的 Z 轴对数切片能精确控制每个地形区块接收的光源数量。
5. 架构对比矩阵
| 架构特性 | Forward | Deferred Shading | Deferred Lighting | Forward+ (Tiled) | Clustered |
|---|---|---|---|---|---|
| 光照复杂度 | |||||
| 光源支持数量 | 极少(< 8) | 海量(数百) | 大量(数十) | 大量(数百) | 海量(数百~千) |
| 带宽 / 显存消耗 | 低 | 极高(G-Buffer MRT) | 中低(薄 G-Buffer) | 中等 | 中偏高(Cluster Buffer) |
| 几何提交次数 | 1 次 | 1 次 | 2 次(致命伤) | 2 次(含 Depth Pre-pass) | 1~2 次 |
| 材质自由度 | 极高 | 受限(G-Buffer 编码) | 高(第二 Pass 自由) | 极高 | 取决于底层管线 |
| 硬件 MSAA | ✅ 原生支持 | ❌ 不支持 | ✅ 支持 | ✅ 支持 | ✅ 支持(Forward 底层) |
| 半透明处理 | ✅ 原生 | ⚠️ 需额外 Forward Pass | ✅ 第二 Pass 处理 | ✅ 原生 | ✅ 统一管线 |
| 体积渲染契合度 | 差 | 一般(需 Depth 绑定) | 一般 | 一般(Tile 深度不连续) | 极佳(纯 3D 空间数据) |
| 移动端适配 | 最佳 | 差(带宽瓶颈) | 较好 | 一般(需 Compute 支持) | 一般 |
| 代表引擎/游戏 | Unity URP Mobile | Unreal Engine 4/5 | Xbox 360 时代主机引擎 | Unity URP Forward+ | Doom (2016)、Frostbite |
6. 选型决策树
1 | |
7. 补充
7.1 Visibility Buffer
(Deferred Materials / Triangle Visibility Buffer)
近年来兴起的新型管线思路,可视为对 Deferred Shading 的再进化,在 Nanite(Unreal Engine 5)中达到工业级实现。
- 核心思想: Geometry Pass 中不存储材质属性,只存储 三角形 ID + 重心坐标(Barycentric Coordinates)(即”谁覆盖了这个像素”的信息,而非”这个像素长什么样”)。Material Pass 中通过三角形 ID 重新索引顶点数据,在屏幕空间按需计算各种材质属性。
- 优势: G-Buffer 极薄(仅两个通道),带宽极低;材质完全灵活(延迟到 Material Pass 才采样纹理);天然兼容 Virtual Geometry(Nanite)。
- 劣势: 实现极度复杂,Shader 代码需要手动执行插值计算(通常需要 Compute Shader + 手写 Barycentric 插值),工程门槛极高。
7.2 TBDR
Tile-Based Deferred Rendering
注意区分”Clustered Deferred”与移动端 GPU 的”TBDR” 架构:
- 移动端 TBDR 是 GPU 硬件架构层面的特性(PowerVR、Mali、Apple GPU),将屏幕划分为小 Tile(如 16×16 像素),在 On-Chip Cache 中完成 Tile 内的完整渲染(包括深度测试、混合),最后才将结果写回显存,从而极大减少显存带宽压力。
- 软件层面的 Clustered Deferred 和 Tiled Forward 是渲染算法,与 TBDR 硬件架构是两个正交的概念,可以在 TBDR GPU 上运行,也可以在 IMR(Immediate Mode Rendering,如 PC 的 NVIDIA/AMD GPU)上运行。
- 在移动端开发中,设计良好的 Forward 管线 + TBDR 硬件加速,通常比 Deferred 管线 + 额外带宽开销更高效。
- 多光源渲染的版本答案:Cluster Shading | 知乎 · 小张
- Olsson, O., Billeter, M., & Assarsson, U. (2012). Clustered Deferred and Forward Shading. HPG 2012.
- Harada, T., McKee, J., & Yang, J. C. (2012). Forward+: Bringing Deferred Lighting to the Next Level. Eurographics 2012.
- A Primer On Efficient Rendering Algorithms & Clustered Shading | Catlike Coding
- Unity URP Forward+ documentation
- Pettineo, M. Forward vs Deferred vs Forward+ Rendering with DirectX 11. MJP’s Blog.