LightOpt: Lights Optimization for Real-time Rendering
Tsinghua University; LIGHTSPEED
一句话总结
LightOpt 用可微渲染把游戏场景里成百上千盏灯”优化压缩”成更少的灯,同时尽量保住原本的画面观感,从而在低端到高端各类平台上把延迟着色的开销降下来。
研究背景
- 领域现状:现代游戏场景常常要靠上百盏灯来营造氛围、突出重点、烘托情绪,视觉密集区域甚至有 10~50 盏灯相互重叠。实时渲染里,光照开销随”每个可见像素要评估的灯数量”线性增长,业界主流靠各种剔除技术(分块剔除、聚簇剔除、tiled-Z 剔除)来缓解。
- 核心痛点:这些剔除方法都是在”固定的灯集合”上做文章——运行时挑一个子集来算,本质没有改变灯的总数。跨平台开发里,为高端和低端设备各自维护一套灯光配置(多灯版 + 少灯但观感接近的版本)非常费人力,主要压在灯光美术身上。LightCuts 一类方法虽然目标相近,但依赖逐视角重算,实时场景下视口一变就得重来,代价高。
- 本文 idea:与其在渲染时”选灯”,不如在预处理阶段直接”改灯集”。作者提出首个可微光照优化流水线,联合优化灯的位置、强度、颜色、方向等参数,并在优化过程中动态地删除、合并、新增灯,得到一套全新的、更紧凑的灯光配置。它与运行时剔除算法正交,可作为前置步骤叠加使用。
方法
整体框架:优化目标不是最终着色图像,而是场景表面的辐照度场(irradiance field)。因为渲染方程把 BRDF 埋在半球积分里、难以直接优化,作者退一步用辐照度场作为”观感”的代理目标。整个流程先在场景表面均匀采样并算出原始辐照度作为目标,然后迭代地在两个子步之间交替:一是固定灯数、用可微渲染优化灯参数逼近原始辐照度场;二是动态调整灯数(删/并/增)。
flowchart LR
A["泊松盘表面采样"] --> B["计算原始辐照度场 E(x)"]
B --> C["可微优化灯参数<br/>拟合辐照度 + 两个损失"]
C --> D["删除低贡献灯"]
D --> E["合并冗余灯"]
E --> F["为欠照区域新增灯"]
F --> C
F --> G["输出紧凑灯集"]
关键设计:
-
辐照度场目标与离散化。表面点 \(x\) 的辐照度是所有灯在其上半球方向的入射贡献之和 \(E(x) = \sum_{l_i \in L} E_i(x)\)。作者用泊松盘采样把表面离散成样本集,并把每盏灯的作用范围扩大到 2 倍,把可达样本标记为 \(S_{\text{all}}\)(含被照亮与未被照亮两类)。由于游戏里多次反弹的全局光照通常已预烘焙,本文只处理直接光照,优化目标近似为对样本求和的 \(\sum_{x \in S_{\text{all}}} (\hat{E}(x) - E(x))^2\)。把灯范围翻倍是关键技巧:让灯跨越影响边界移动时目标仍然可微。
-
重叠损失(Overlap Loss)。在分块/聚簇渲染里,每个 tile 的开销约正比于”像素数 × 光照列表长度”。直接优化逐视角逐 tile 的灯表不现实,于是作者定义了一个近似的重叠损失 \(l_o\):对每个样本统计能影响它的灯集合 \(L_x\),当 \(\lvert L_x \rvert\) 超过用户设定的最大重叠阈值 \(n_{\max}\) 时用二次惩罚 \(\alpha(n) = (\max(0, n - n_{\max}))^2\) 施压,并用一个基于辐照度的 softmax 软权重优先移除贡献弱的灯。惩罚项用到平滑的”到边界距离”(点光用 softplus、聚光灯再取径向与角向距离的 softmin),保证可微。效果上它压低了每 tile 平均灯表长度。
-
吸引损失(Attraction Loss)。只用重叠损失会把灯从密照区推开,可能留下欠照空洞;而落在所有灯范围之外的样本几乎没有梯度去”拉”远处的灯过来。为此作者定义欠照样本集 \(S_{\text{under-lit}} = \{x \mid \hat{E}(x) \le \epsilon_u E(x)\}\),为每个欠照样本挑选前向朝向且足够近的候选灯(搜索半径按灯的有效范围自适应,范围越小的灯给越大的补偿搜索区),用几何距离惩罚把附近的灯往欠照区拉近或扩大其覆盖。
-
动态灯集调整(删 / 并 / 增)。删除:用一盏灯对辐照度场的总贡献 \(\gamma_i\) 衡量重要度,低于阈值 \(\epsilon_i\) 的直接剪掉。合并:用两盏灯照亮样本集之间的 Chamfer 距离衡量相似度,合并代价 \(M(i,j) = \gamma_i \gamma_j d(S_i, S_j)\),取代价最低的 10% 对,若能降低重叠损失且新灯 80% 以上样本前向可见就合并,并用重要度加权平均初始化新灯参数(锥角超过 \(130^\circ\) 阈值就转成点光)。新增:把欠照样本用 DBSCAN 聚类,累计重要度超阈值的簇里生成新灯,参数由簇统计初始化、并沿平均法向搜索最优位置。
此外,作者把优化扩展到 Time-of-Day(ToD)光照:每盏 ToD 灯由稀疏关键帧描述、帧间分段线性插值,优化时引入时间维度、在全局关键帧集合上用非均匀梯形法则做数值积分加权求和,与游戏引擎的关键帧插值管线对齐。
实验结果
在 Unity + tiled-Z 剔除的延迟着色管线、RTX 3090、1920×1080 下,评测了 5 个真实游戏场景(80~300+ 盏灯)。核心结论用”输入 / 工业常用法 / 本文”三者在灯数、平均光重叠 ALO、延迟着色时间与 RMSE 上的对比呈现(工业法把每视锥灯数上限固定为 32,视角相关):
| 场景 | 方法 | 灯数 | ALO (mean) | 着色 ms (mean) | RMSE (mean) |
|---|---|---|---|---|---|
| Valley | Input | 121 | 5.78 | 0.95 | - |
| Valley | 工业法 | 32 | 4.46 | 0.75 | 0.055 |
| Valley | 本文 | 57 | 2.54 | 0.57 | 0.046 |
| Tavern | Input | 210 | 3.35 | 0.71 | - |
| Tavern | 本文 | 126 | 1.72 | 0.52 | 0.041 |
| Cave | Input | 80 | 3.43 | 0.71 | - |
| Cave | 本文 | 64 | 2.05 | 0.49 | 0.037 |
| Street | Input | 135 | 3.83 | 0.67 | - |
| Street | 本文 | 95 | 1.68 | 0.45 | 0.033 |
整体上,本文把活跃灯数减少 20~53%、光照开销降低 18~52%,各场景平均加速 1.37~1.67 倍、复杂光照下最高 2.07 倍。相比工业常用法(依赖相机位姿、倾向丢远处灯、加速有限且远景细节退化)和美术手工削减(为达实时约束激进删光、RMSE 明显更高),本文在着色时间与 RMSE 上都更优。
其余实验用文字概述:跨平台测试(RTX 3090 / RTX 2080 / Intel UHD 630 集显)显示相对加速比在三档硬件上基本一致,且绝对收益在低端硬件上最显著——Valley 场景在集显上平均延迟着色时间最多降低 39.7 ms。消融实验表明:重叠损失权重 \(a_o\) 越大、ALO 越低但 RMSE 越高,体现质量-效率权衡;吸引损失体积 \(v\) 过小会留下欠照硬边、过大又会把光照分配到不该亮的区域;动态灯集调整与吸引损失协同才能有效消除欠照伪影;重要度阈值 \(\epsilon_i\) 过大会过度剪枝短程灯、丢失细节。
亮点与局限
- 亮点:
- 视角切换:从”运行时选灯”转到”预处理阶段重构灯集”,与已有剔除/采样算法正交,可直接叠加进现有工业管线而不改渲染算法本身。
- 用辐照度场作为可微优化的代理目标,避开了 BRDF 半球积分难以直接优化的问题;配合”灯范围翻倍”保证跨边界移动时可微。
- 两个损失分工明确(重叠损失去冗余、吸引损失补欠照),加上删/并/增的动态调整,形成一套自洽的多目标优化,且对 ToD 动态光照有自然扩展。
- 有真实生产场景验证与跨平台评测,低端设备收益尤其突出,实用性强。
- 局限:
- 优化保的是辐照度场而非最终着色图像,不显式建模视角相关效果(如高光),在强高光材质或锐利光照过渡处会有偏差。
- 删/并/增是离散操作,尚未做到完全可微。
- 假设优化后的灯单位可见性(不处理阴影投射灯),扩展到阴影灯需要在可微优化中处理不连续可见性。
- 目前不支持面光源与环境光照;含植被、薄几何或强重叠的场景仍可能在优化后出现欠照。
延伸思考
- 这条思路和 LightCuts 系(构建灯层级、逐像素选子集)以及 ReSTIR、MegaLights 等运行时采样/剔除方法是互补关系:前者动”用哪些灯来算”,本文动”场景里到底有哪些灯”,两者叠加理论上能进一步压成本。
- 把优化目标从辐照度场升级为”感知驱动”或”BRDF-aware”的度量,或许能兼顾高光等视角相关效果,是最直接的改进方向。
- 让离散的删/并/增操作可微、把阴影投射灯的不连续可见性纳入优化,是打通”端到端全可微光照重构”的两块硬骨头;面光源与环境光的可微处理则是扩大适用范围的自然延伸。
- 对做实时渲染管线的团队,这类”离线预处理换取运行时省算力”的范式很值得借鉴——把美术手工调灯的重复劳动交给优化器,还能顺带产出跨平台的多档配置。