中EN
概念页

分簇着色

Clustered Shading

分簇着色把整个视锥(而不只是屏幕平面)划分为三维单元——簇 (cluster),按簇建立光源列表。与依赖场景几何深度的分块着色不同,簇的划分与几何无关,可只由视图和光源计算,因此对相机位置的性能波动更小、对深度不连续更稳健,并为不透明、透明、体积物体提供统一的光照方案。它同样可配合前向或延迟着色,并衍生出 z-binning、光源树等更省内存的变体。本页还汇总了各类多光源方案的对比。

簇的划分(20.4 节)

透视下瓦片截面随距离增大,均匀划分深度会得到扁平或细长的体素。Olsson 等人在视空间按指数划分深度(不依赖几何的 zminz_{min}/zmaxz_{max}),使簇更接近立方体。实例:《正当防卫 3》用 64×64 像素瓦片 16 个深度切片;Unreal Engine 用同样大小的瓦片,通常 32 个深度切片。

flowchart LR
  A["视锥按屏幕瓦片 x 深度切片划分为簇"] --> B["光源与簇求交, 生成每簇光源列表"]
  B --> C["任意表面按自身位置查所在簇"]
  C --> D["不透明: 前向或延迟"]
  C --> E["透明与体积: 前向"]

如上图,任何表面——不透明或透明——都用自身位置找到簇并取光源列表。

前向还是延迟

  • 《极限竞速:地平线 2》在 GPU 上算簇,再用前向着色,因为这样无需额外工作即可支持 MSAA。单遍前向会有过度绘制,可用粗略前到后排序或只对部分物体做预通道缓解;但 Pettineo 发现即使如此,单独 z-prepass 仍更快。
  • 《正当防卫 3》不透明用延迟、透明用同一光源列表做前向,光源列表在 CPU 上生成;Dufresne 也在 CPU 上并行生成,因为这一过程不依赖场景几何。

相对分块着色的优势

每个列表光源更少、视角依赖更小。瓦片的细长视锥会因相机微小移动而内容剧变——一排直线路灯可能恰好对齐填满一个瓦片;即使用深度细分,单个像素变化也可能使瓦片的近远距离剧烈跳动。分簇方式对此不敏感。

优化

  • 为光源建 BVH 快速判断与簇的重叠(任一光源移动就需重建);大量光源时排序很贵。
  • 延迟着色下按簇内表面的量化法线方向剔除:Olsson 等把法线归入立方体每面 3×3、共 54 个方向组成法线锥,剔除位于簇内所有表面背后的光源。
  • 有可见几何深度时(延迟或 z-prepass)可剔除空簇得到稀疏网格,但需先找出被占用的簇,只能在 GPU 上进行;还可用簇内样本构造紧 AABB 剔除更多光源。优化后的系统能处理上百万个光源,随光源数扩展良好,光源很少时也高效。
  • 深度不必按指数划分:指数分布使远处簇体积大、光源列表过长。对策是限制分簇的"远平面",更远的光源淡出、用粒子或眩光表示或烘焙,或用更简单的着色器、lightcuts 等 LOD 技术;反之最近处簇细分很密但往往很空,可把分类视锥的"近平面"推到合理距离,更近的光源都归入第一切片。

光源插入方式

  • 《DOOM》(2016):结合 Olsson 与 Persson 的方法实现分簇前向。z-prepass 约 0.5 ms;建表可视为裁剪空间体素化:对每个单元的 AABB 测试插入光源、环境光照探针和贴花。加入贴花使分簇前向也获得延迟着色在贴花上的优势,且混合方式任意、可用于透明表面。
  • CPU 解析测试:球与簇盒的解析测试便宜,不需要几何;但聚光灯若用包围球会被加入许多无关簇,精确解析测试又贵。Persson 给出快速把球体素化到簇的方法。
  • GPU 光栅化插入(Örtegren 与 Persson):两遍——壳 pass 用包住光源的低分辨率网格做保守光栅化,记录每个光源覆盖的最小和最大簇;填充 pass 用计算着色器把光源加入这两者之间每个簇的链表。网格比包围球对聚光灯更紧,几何还能直接遮挡光源可见性。无保守光栅化时,Pettineo 用表面深度梯度选择像素最远(或最近)角计算深度,并截断到光源整体深度范围,防止接近侧视的三角形估计失真。Wronski 给每个网格单元套包围球与锥做相交测试,单元接近立方体时快且好用,细长时较差。
  • 《使命召唤:无限战争》(Drobot):把静态聚光灯基于静态几何的阴影贴图烘焙成保守的低分辨率网格(取每块区域的最大深度),作为光源的有效体积,覆盖的簇远少于原始锥体。

z-binning

同样来自 Drobot,存储远少于分簇着色:光源按屏幕深度排序并按深度分配 ID;用等厚(而非指数)的 z 切片分类,每个切片只存与之重叠光源的最小和最大 ID;另外生成二维瓦片光源列表(几何剔除可选)。像素着色时取瓦片列表,再用自身深度取所在切片的 ID 范围,两者交集即为该簇的有效光源。

方案存储每像素工作
分簇每个三维簇一个列表直接读取
z-binning每个二维瓦片一个列表 + 一个小的定长切片数组实时求交,略多

可能误分类部分光源,但 Drobot 发现人造环境中光源在 xy 与 z 上很少同时重叠,在深度不连续的瓦片中也能得到近乎完美的剔除。

其他结构

三维访问结构可分为体积型(网格、八叉树)、物体型(BVH)与混合型。Bezrati 让瓦片光源列表中每个光源附带最小和最大深度,片元可快速拒绝不重叠的光源。O'Donnell 与 Chajdas 的分块光源树在 CPU 上对每个瓦片内光源的 z 范围建一维包围区间层次,比三维层次简单,适合 GPU,并能处理大量光源落入同一瓦片的情形;他们还给出在簇划分与光源树之间选择的混合算法,光源树在单元与光源平均重叠较低时效果最好。

移动端

  • 移动 GPU 把 G-buffer 保留在片上本地内存,所以传统逐光源延迟反而可能最高效。
  • OpenGL ES 2.0 即可实现 tiled forward;OpenGL ES 3.0 加像素本地存储 (pixel local storage) 扩展可利用 ARM GPU 的分块渲染高效生成和应用光源列表。
  • Frostbite 移植到移动端时,因为移动端计算着色器支持较弱,需要在光源分类方案上取舍。framebuffer fetch 与像素本地存储可把整体带宽降低一半以上。

方案对比(典型桌面 GPU,表 20.1,据 Olsson)

项目传统前向传统延迟分块/分簇延迟分块/分簇前向
几何 pass1111~2
光照 pass0每光源 111
光源剔除粒度每网格每像素每体积每体积
透明容易不支持需配合前向容易
MSAA内建难难内建
带宽低高中低
多种着色模型简单难较复杂简单
小三角形慢快快慢
寄存器压力可能高低可能低可能高
阴影贴图复用否是否否
贴花昂贵便宜便宜昂贵

说明:小三角形一栏反映前向着色中 quad 着色四个样本都完整计算的低效;分块/分簇延迟若采用着色器精简(见 分块着色)寄存器压力可以很低;阴影贴图复用在显存充裕的今天已不那么关键。

多光源阴影与世界空间分簇

  • 光源很多时阴影是挑战:常见做法是只为最近、最亮的光源和太阳计算阴影,代价是次要光源漏光;Harada 等在 tiled forward 中为每个可见像素向附近光源发射光线;Olsson 等用被占用的网格单元作为几何代理按需生成阴影贴图,并与光线投射混合。
  • 也可在世界空间而非屏幕空间生成光源列表,但大场景受内存限制,且远处簇只有像素大小,影响性能;Persson 提供了把静态光源存入三维世界空间网格的基础分簇前向代码。

总结

分块、分簇等光源列表剔除可用于延迟或前向,也可用于贴花;光源体积剔除旨在减少每个片元评估的光源数,而几何与着色解耦用于平衡计算与带宽。和视锥剔除一样,在某些条件下这些技术收益很小:只有太阳时不需要光源剔除;有大量有限范围光源时,建立局部光源列表无论前向还是延迟都值得。"哪个更好"的答案是"看情况":平台、场景、光照模型、设计目标都有影响。

  1. realtime_rendering_4ed.pdf 第 20 章 Efficient Shading

相关页面

图形学分块着色Tiled Shading分块着色把屏幕划分为瓦片(如 32×32 像素),先为每个瓦片建立可能影响它的光源列表,着色时每个像素在一次着色器调用中只遍历所在瓦片的列表。它可用于延迟着色(tiled deferred),也可用于前向着色(tiled forward,又称 Forward+)。配合 z-prepass 得到的瓦片深度范围可进一步剔除光源,但深度不连续会削弱效果,于是出现 HalfZ、2.5D 剔除等改进。图形学延迟着色Deferred Shading延迟着色先用一遍几何 pass 把所有可见表面的材质参数写入多张渲染目标(G-buffer),再以后处理方式对这些存储值逐光源计算光照,从而把"几何可见性"与"光照"彻底解耦,并把材质与光源分离。它避免了着色的过度绘制、简化了着色器管理、天然适合贴花,但 G-buffer 占用显存和带宽,且难以直接支持透明和 MSAA。本页也覆盖前向渲染下限制光源影响范围的基础手段与"光照预通道 (light prepass)"类混合方案。图形学贴花渲染Decal Rendering贴花 (decal) 是叠加在表面上的图案或纹理,如轮胎印、弹孔、玩家喷漆、标志。贴花可只改颜色(纹身)、只改凹凸(压印标志)或换成完全不同的材质(车窗贴纸),可多个叠在同一几何上,也可横跨多个模型。主流做法是用有向盒做正交投影的投影贴花;延迟着色把贴花效果直接写进 G-buffer,分簇前向着色则把贴花像光源一样放进簇列表。图形学空间数据结构Spatial Data Structures空间数据结构把几何体按 n 维空间组织起来,通常是层次化的树,使"几何体是否重叠"一类查询从 O(n) 降到大约 O(\log n)。常见类型有包围体层次 (BVH)、BSP 树(轴对齐的 k-d 树与多边形对齐两种)、四叉树/八叉树(含松散八叉树),以及更偏向组织模型关系的场景图。它们是剔除、光线求交、碰撞检测等加速算法的基础。图形学剔除技术Culling Techniques剔除 (culling) 是在渲染前尽快去掉对最终图像没有贡献的部分。本页讲几何类剔除:背面剔除(含成簇背面剔除与法线锥)、视锥剔除(层次化、平面掩码)、室内场景的入口剔除,以及牺牲质量换速度的细节剔除和小三角形剔除。更复杂的遮挡剔除见 遮挡剔除。图形学光栅化Rasterization光栅化(也叫扫描转换)把屏幕空间里带深度和着色数据的顶点,转换成三角形覆盖的像素(片元),交给像素处理阶段。它是几何处理和像素处理之间的同步点:三个顶点在这里组成三角形。图形学阴影贴图Shadow Mapping阴影贴图 (Williams, 1978) 先从光源位置渲染深度,再从相机渲染时把每个点到光源的距离与贴图中存的深度比较:更远就在阴影中。它开销可预测(生成约与图元数成线性、查询为常数时间),非常适合 GPU,是任意表面阴影最常用的算法。主要问题是分辨率、深度精度带来的混叠、阴影痤疮和漏光。图形学参与介质与体积散射Participating Media & Volumetric Scattering参与介质是充满粒子、通过吸收和散射参与光传输的体积,如空气、水、雾、烟、云;皮肤、蜡等致密材质也有强烈散射——"一切都是散射"。实时渲染主要考虑单次散射:沿视线积分透射率衰减后的内散射光,内散射由相位函数和对光源的可见性(不透明阴影 × 体积阴影)决定。通用实时方案把介质材质和散射结果体素化到相机视锥体素 (froxel) 中逐片累积(RTR4 14.1、14.3、14.8 节)。游戏开发 · UE5UE5 渲染架构UE5 Rendering ArchitectureUE5 的渲染器是独立的 Renderer 模块,在渲染线程 (Rendering Thread) 上以「场景代理」镜像游戏线程的组件状态,每帧按固定顺序执行深度预通道、G-buffer 基础通道、光照、雾、半透明和后处理。现代渲染代码用渲染依赖图 (Render Dependency Graph, RDG) 声明通道与资源,由 RDG 自动排屏障、复用瞬态内存、并行录制;最终命令经 RHI 线程翻译成 D3D12/Vulkan 等图形 API 调用。默认走延迟着色 (Deferred Shading),也可切换前向着色 (Forward Shading)。综合帧时间预算与渲染性能Frame Budget & Rendering Performance本页把 wiki 中分散在 RTR4 第 18~23 章的性能知识串成一条线:一帧的时间预算由最慢的管线阶段决定,先用毫秒帧时间度量并定位瓶颈,再按瓶颈所在位置——CPU/驱动、几何、像素、带宽/内存——选用对应手段;最后从 GPU 硬件机制(占用率、HiZ/early-z、压缩、分块架构)理解这些手段为何有效。各结论的细节与出处见所链接的概念页。图形学着色模型与光源Shading Models & Light Sources着色模型描述物体颜色如何随表面朝向、观察方向和光照变化。光源通过两个参数与着色模型交互:指向光源的方向 \mathbf{l} 和光的颜色 \mathbf{c}{\text{light}}。方向光、点光源、聚光灯的区别就在于这两个量如何随场景变化;距离衰减和方向衰减函数的选择同时影响画面与性能。图形学延迟纹理与可见性缓冲Deferred Texturing & Visibility Buffer延迟着色避免了着色的过度绘制,但生成 G-buffer 时仍有过度绘制:先画的物体读了大量纹理,被后画的物体挡住后这些带宽全部浪费。延迟纹理只用一遍几何 pass、存极少的数据(纹理坐标与切线基,或仅三角形与实例 ID),直到着色时才读纹理。由于 GPU 算力增长快于带宽,让瓶颈落在计算而非缓冲访问被视为面向未来的做法。图形学像素着色器Pixel Shader像素着色器(OpenGL 里叫片元着色器)对光栅化产生的每个片元运行,用插值后的顶点数据算出颜色,也可以输出不透明度、修改深度或直接丢弃片元。多渲染目标让它一次输出多组数据,催生了延迟着色。它通常只能写自己所在的像素,但能通过 2×2 quad 拿到相邻像素的导数。图形学多光源采样与光源 BVHMany-Light Sampling & Light BVH场景有成百上千个光源时,不可能在每个着色点对所有光源做直接光照。利用求和的蒙特卡洛估计 \sumi fi\approx fj/p(j),每次只随机选一个(或几个)光源并除以其概率即可无偏。选择概率可以均匀、按功率,或随着色点变化——后者需要一棵把光源聚合起来的层次结构(光源 BVH)。本页对应 PBRT 4e 12.6 节,并对照实时渲染的分簇/分块光源剔除。

输入关键词开始搜索

滚轮或双指缩放 · 拖动平移 · 双击放大 / 还原