基于 Surfel 的全局光照(GIBS)

Global Illumination Based on Surfels


技术概述与背景

什么是 GIBS

  • GIBS(Global Illumination Based on Surfels) 是一种用于 实时计算间接漫反射光照 的方案
  • 由 Electronic Arts 的 SEED R&D 组Frostbite 引擎团队 联合开发
  • 核心思路:将 硬件光线追踪(Hardware Ray Tracing)场景几何的离散化(Discretization) 相结合,在时间和空间上 缓存并分摊光照计算开销

核心优势

  • 无需任何预计算 :不需要 lightmap 烘焙、不需要特殊的 mesh、不需要特殊的 UV 集
  • 支持高保真光照 :可处理任意规模的内容(从小物件到大型环境)
  • 全动态 :支持蒙皮角色、动态物体、复杂动态光照交互,场景中所有物体都可以变化
  • 加速制作流程 :省去了耗时的烘焙和传统光照技术的繁琐设置工作

与其他方案的对比

对比方案GIBS 的优势
Probe Grid(探针网格)方案GIBS 在场景表面上精确执行光线追踪和缓存,而非在空间中均匀撒探针
屏幕空间滤波/缓存技术Surfel 缓存是 持久化的(Persistent) ,当表面移出视野再回来时无需重新计算

发展历史

  • 原始 GIBS 算法于 2018 年 作为 EA SEED 的 PICA PICA 光追 Demo 的一部分实现(主要作者:Tomasz Stachowiak)
  • 之后经过大幅 扩展和优化 ,能够处理任意几何体(包括蒙皮角色和大型环境),同时改善了收敛时间和质量
  • 现已成为 Frostbite 引擎 工具集的一部分,供 EA 内部各开发团队使用

⚠️ 讲者强调该技术仍在持续开发中,预计还会有显著改进。


什么是 Surfel

基本概念

  • 类比:就像一张图像可以被 像素(Pixel) 离散化一样,一个几何表面也可以被离散化
  • SurfelSurface Element(表面元素) 的简写
  • 每个 Surfel 由三个属性定义:
    • 位置(Position)
    • 半径(Radius)
    • 法线(Normal)
  • 近似描述了给定位置附近的一小块表面邻域

为什么适合全局光照

  • 分辨率无关(Resolution Independent) :性能和质量可灵活扩展
  • 在表面上精确地执行和缓存光追操作 —— "在需要的地方做需要的事"
  • 持久化缓存避免重复计算

场景的 Surfel 化(Surfelization)

生成流程

  1. 当几何体 进入视野 时,从 G-Buffer生成(Spawn) Surfel
  2. 生成后 Surfel 是 持久化的 ,可以高效地跨帧 累积辐照度(Accumulate Radiance)
  3. 缓存了昂贵的计算结果,不会因物体暂时离开屏幕就丢弃

生成算法细节

  • 屏幕空间 Tile 划分 :屏幕被划分为 16×16 的 Tile
  • 每个 Tile 找到当前 覆盖率最低的纹素(Texel)
  • 如果覆盖率低于一个 随机化阈值(Randomized Threshold) ,就使用 G-Buffer 中的几何信息生成一个新的 Surfel
  • 当某个 Tile 达到一定覆盖率后,停止生成新 Surfel
  • 正常情况下生成速度足够快,用户 几乎感知不到覆盖空洞

更多生成细节可参考 Tomasz 2018 年的演讲。


Transform ID 与动态跟踪

机制原理

  • Surfel 虽然是持久化的,但 每帧都会更新其位置 ,以跟随它所附着的表面
  • 实现方式:每个 Surfel 追踪一个 唯一的 Transform 标识符(Transform ID)
  • 这个 ID 在生成时从 G-Buffer 中获取

Frostbite 中的实现

  • Frostbite 维护了一个 全局 Transform 缓冲区(Global Transform Buffer) ,包含场景中所有几何体的变换信息(包括 骨骼蒙皮的骨骼变换
  • 每帧利用 Surfel 的 相对位置(Relative Position) + Transform ID + 全局 Transform 缓冲区 → 计算出新的 世界空间位置

蒙皮网格(Skinned Meshes)支持

工作方式

  • 对于蒙皮几何体,写入 G-Buffer 时使用的 Transform ID 是 权重最高的那根骨骼的 ID
  • 这等效于对 Surfel 做 单骨骼蒙皮(One Bone Skinning) ,即使原始网格使用了任意数量的蒙皮权重

精度与容错

  • 由于只使用一根骨骼,某些情况下 Surfel 不会完全精确地跟随表面
  • 但 Surfel 的应用算法对此有较好的 容错性(Fairly Forgiving)

动态交互

  • 因为 GIBS 假设一切都是动态的,所以 蒙皮和运动中的几何体 与静态几何体以完全相同的方式参与全局光照
  • 蒙皮几何体同时 投射和接收全局光照

尺度自适应(Scale)

屏幕空间恒定密度

  • Surfel 化在 任意距离 下都能工作
  • Surfel 的大小会被缩放,使得它们在 屏幕空间中的投影大致恒定
  • 这既适用于 生成时 ,也适用于 相机移动时

具体行为

相机操作Surfel 行为
靠近物体Surfel 缩小 ,同时 生成更多新 Surfel 以维持屏幕空间密度
远离物体Surfel 放大移除多余 Surfel (覆盖率过高的地方)

重要意义

  • 质量恒定 :无论远近,光照质量保持一致
  • 性能恒定 :由于屏幕空间 Surfel 密度恒定,计算量也大致恒定 —— 这是一个非常重要的性能特性

Surfel 管理与内存控制

资源预分配策略

  • 由于 Surfel 是在移动过程中动态生成的,必须控制 内存和性能的一致性
  • 解决方案:算法在初始化时 预先分配所有 Surfel 管理所需的资源
  • 这意味着存在一个 Surfel 总数上限

Surfel 回收算法(Recycling)

为了有效利用有限资源,使用了一个基于 栈(Stack) 的回收机制:

  1. 初始化 :关卡加载时,栈中包含指向整个 Surfel 空间的 间接索引(Indirections)
  2. 生成 Surfel :通过 GPU 上的 原子操作(Atomic Operation) 递减栈计数器,从栈顶取出可用 Surfel 的 ID
  3. 回收 Surfel :当某个 Surfel 不再需要时(被判定为 "不再相关"),递增栈计数器,并将其 ID 写回栈缓冲区

关键实现特点

  • 全部在 GPU 上完成 :生成、回收、管理操作均不涉及 CPU 回读,保证了高效的 GPU 驱动流水线
  • 预分配 + 栈式管理 = 零运行时内存分配 ,内存占用完全可预测

Surfel 回收启发式算法(Recycling Heuristic)

为什么需要回收

  • 系统维护一个 全局 Surfel 预算(Global Budget) ,用一个进度条显示当前存活的 Surfel 数量占总预算的比例
  • 回收算法负责将存活 Surfel 数量控制在预算内
  • 不能过度回收 ——每个 Surfel 上已经积累了大量光照计算结果,丢弃意味着浪费之前的工作

启发式因子

回收决策基于以下几个因素的综合评估:

  1. 当前存活 Surfel 数量 :总量越接近预算上限,回收压力越大
  2. 上次贡献时间 :该 Surfel 最后一次对场景光照产生贡献的时间戳(越久未贡献越容易被回收)
  3. 距离 :Surfel 与摄像机的距离(越远越容易被回收)

回收机制

  • 将上述因子组合后与一个 均匀分布的随机数 进行比较
  • 相关性越低的 Surfel 被赋予 更高的回收概率
  • 这是一种 概率性淘汰 策略,避免了硬性截断带来的视觉跳变

加速结构(Acceleration Structure)

问题背景

  • 算法中很多步骤需要 快速查找给定位置附近的 Surfel
  • 原始 PICA PICA 版本使用了 均匀网格(Uniform Grid) 来加速空间查询

均匀网格的工作方式

  1. 每帧将所有 Surfel 插入网格
  2. 根据 Surfel 的位置计算其所在的网格单元(均匀网格下这是一个简单运算)
  3. 由于 Surfel 有半径,需检查是否与 相邻单元重叠 ,若重叠则也插入相邻单元
  4. 保证 Surfel 半径永远不超过网格单元边长 ,因此只需检查 直接相邻的单元

均匀网格的局限性

  • 对 PICA PICA 的小场景效果很好,但 无法扩展到现代游戏的大规模关卡
  • 回顾前面提到的:Surfel 半径在 屏幕空间大致恒定 ,这意味着 远处的 Surfel 在世界空间中半径很大
  • 为了避免光照应用或查找时的不连续性,就需要使用 非常大的网格单元尺寸 ,这会 抵消均匀网格带来的加速优势

理想加速结构的需求

  • 需要类似 投影变换(Projection Transform) 的特性:近处分辨率高,远处分辨率低
  • 同时要 足够简单 ,确保查找速度快

最终方案:均匀网格 + 梯形网格(Uniform + Trapezoidal Grid)

  • 近处 :保持一个 均匀网格 区域
  • 远处 :沿每个 主轴方向(Principal Axis) 使用 梯形网格(Trapezoidal Grid)
  • 梯形网格的 切片厚度随距中心距离增大而增大

关键特性

  • 完美匹配 Surfel 随距离增长的方式 :远处网格单元更大,正好容纳远处更大的 Surfel
  • 查找和插入依然非常快 :梯形网格本质上是均匀网格加上一个 非线性变换
  • 调试可视化显示:
    • 中心灰色区域 = 线性增长的均匀网格
    • 周围粉色/绿色/黄色区域 = 非均匀的梯形网格
    • 视觉上梯形网格在不同距离下保持 恒定的网格单元视觉大小 (类似光学错觉效果)

热力图观察

  • 几何复杂度高的区域 → 更多 Surfel 生成 → 每个网格单元中 Surfel 密度更高

光照应用(Light Apply)

应用流程

  1. 对每个 屏幕空间像素 ,重建其 世界空间位置
  2. 在加速结构中找到 覆盖该位置的网格单元
  3. 获取该单元中 所有已插入的 Surfel
  4. 遍历所有 Surfel,将每个 Surfel 视为 虚拟点光源(Virtual Point Light)
  5. 根据以下因素 加权 计算对当前像素的辐照度贡献:
    • Surfel 与像素之间的 距离
    • Surfel 与像素的 朝向关系(Orientation)
    • 其他几何因子

光照渗漏问题(Light Bleeding)

现象描述

  • 以上述方式应用光照时,可能在墙壁和天花板上出现 斑块状伪影(Blotchy Artifacts)
  • 地板靠近墙壁的区域也会出现类似问题

原因分析

  • 某些 Surfel 之前生成在室外更明亮的环境中
  • 这些 Surfel 在其半径范围内 对所有临近的表面都施加了光照 ,包括墙壁另一侧
  • 根本原因:Surfel 本身并不知道周围的几何遮挡关系

深度函数(Depth Function)

解决思路

  • 为每个 Surfel 构建一个 深度函数(Depth Function) ,让 Surfel "感知"周围的几何环境
  • 初始化为 Surfel 的半径
  • 在累积辐照度的光线追踪过程中,如果在半径范围内检测到几何体,就 更新深度函数 以表示该几何体的存在

径向高斯深度(Radial Gaussian Depth)

存储方式

  • 不仅仅存储深度值,而是存储深度的 滑动平均(Moving Average)
    • 深度均值
    • 深度平方均值
  • 由此可以重建:
    • 均值估计(Mean Estimate)
    • 方差估计(Variance Estimate)

切比雪夫不等式深度测试(Chebyshev's Inequality)

  • 利用均值和方差,通过 切比雪夫不等式(Chebyshev's Inequality) 进行 软深度测试

  • 提供了一个 平滑的深度测试 ,在深度空间中 非常适合重建斜面/坡度(Slopes)
  • 该技术灵感来源于 方差阴影贴图(Variance Shadow Maps, VSM)DDGI

与 DDGI 的区别

DDGIGIBS
深度关注范围探针的完整视角仅关注 Surfel 直径范围内 的深度("有先天优势")
方向关注全球面仅关注半球

深度图分辨率

  • 可配置,但大多数情况下每个 Surfel 仅使用 4×4 纹素 的深度图(对应半球)
  • 即便如此低的分辨率,配合切比雪夫不等式也 足以消除渗漏伪影

效果

  • 应用深度函数后,墙壁和天花板上的 斑块伪影完全消失
  • 室内外交界区域的光照渗漏问题得到 有效缓解

辐照度积分(Integrating Irradiance)

设计目标

  • 一切都是 动态的 :支持自发光表面和材质、可破坏环境、动态物体
  • 需要 高效积分辐照度 并对场景变化做出快速响应

基本光线追踪算法

以一个合成场景为例(地面上有 Surfel、蓝色天空、光源和一些几何体):

  1. 从 Surfel 向场景 随机发射光线
  2. 若未命中任何几何体(Miss)
    • 认为命中了天空
    • 在该方向评估 天空光照(Sky Lighting)
  3. 若命中几何体(Hit)
    • 需要评估来自场景光源的 直接光照
    • 向光源发射 遮挡/阴影光线(Shadow Rays)
      • 若阴影光线被遮挡 → 该方向无贡献
      • 若阴影光线未被遮挡 → 有光照贡献
    • 在命中点评估 BRDF ,将结果沿原方向返回

多次弹射(Multi-Bounce)

  • 上述过程只能得到 单次弹射(Single Bounce) 的间接光照
  • 但命中点上可能 已经存在其他 Surfel ,这些 Surfel 随时间已经积累了辐照度
  • 利用命中点处 Surfel 的已缓存辐照度 ,可以 随时间获得无限次弹射(Infinite Bounce) 的光照效果

时间分摊策略

  • 为了支持动态环境并 降低单帧光追开销 ,不需要一次性发射所有光线
  • 光线 分摊到多帧 完成累积
  • 使用 修改版的滑动平均估计器(Modified Moving Average Estimator) 来融合多帧结果

这种设计使得系统既能保持实时性能,又能随时间收敛到高质量的全局光照结果。

积分器(Integrator)—— 自适应混合估计

常规移动平均的困境

  • 普通的 移动平均估计器(Moving Average Estimator) 需要手动选择一个 混合因子(Blend Factor)
  • 这带来了一个两难选择:
    • 混合因子大 → 响应快 ,但噪声多、不收敛
    • 混合因子小 → 收敛好 ,但对场景变化反应迟钝
  • 理想目标:两者兼得 ,且全自动

多尺度均值估计器(Multi-Scale Mean Estimator)

  • 在积累 长期移动平均(Long-Term Moving Average) 的同时,额外追踪:
    • 短期均值(Short-Term Mean)
    • 短期方差(Short-Term Variance)
  • 短期估计器用于 动态调整长期均值的混合因子
  • 效果:场景变化时快速响应,稳定后收敛到无噪声结果

📎 相关代码已开源在 GitHub 上(Multi-Scale Mean Estimator),详见 Tomasz 2018 年演讲。

基于方差的自适应光线数量

由于每个 Surfel 都在追踪方差,可以将方差信息用于 自适应调节每帧发射的光线数量

方差状态光线策略
高方差发射 更多光线 ,加速收敛
低方差发射 极少光线 ,节省开销
已收敛进入 近休眠状态(Almost Dormant State) ,可能每帧仅 1 条光线,甚至每隔几帧 1 条

可视化表现

  • 蓝色 = 低方差(已收敛区域)
  • 红色 = 高方差(需要更多光线的区域)
  • 场景变化发生时(物体移动或灯光改变)→ Surfel 方差飙升 → 光线数量自动增加 → 快速收敛 → 回到休眠状态
  • 新区域进入视野时,新生成的 Surfel 初始方差高 → 快速发射大量光线 → 收敛后自动降低

全局光线预算(Global Ray Budget)

  • 每个 Surfel 独立请求自己需要的光线数量
  • 系统维护一个 全局用户定义的光线预算 ,将所有 Surfel 的请求总和与该预算进行比较
  • 确保 性能可预测 :无论场景复杂度如何,总光线数量始终受控

BRDF 重要性采样(Importance Sampling the BRDF)

朴素方法

  • 最简单的方式:在 半球上均匀发射光线
  • 效率低,浪费大量光线在贡献小的方向上

余弦采样(Cosine Lobe Sampling)

  • 由于 BRDF 是 Lambertian(漫反射) ,可以对 余弦波瓣(Cosine Lobe) 进行重要性采样
  • 即:在 法线方向附近(BRDF 值较大的方向) 发射更多光线
  • 在大多数环境中效果良好,但在 光照方向与法线方向不一致 的场景中效果很差

光线引导(Ray Guiding)

问题场景

  • 当大部分光线来自 与法线无关的特定方向 时,余弦采样效率极低
  • 例:一个房间中只有右侧墙壁被阳光直射,其余区域很暗
    • 两个 Surfel 发射相同数量和方向的光线
    • 靠近亮墙的 Surfel 命中光源的概率是远处 Surfel 的 两倍
    • 远处 Surfel 因估计不准而表现为明显 噪声
  • 核心需求:精确了解光照从哪个方向来 ,在那些方向上集中发射光线

理论基础

  • 灵感来自:
    • Müller 等人的 Practical Path Guiding for Efficient Light Transport Simulation :在空间二叉树的每个节点上构建球面四叉树,细分直到每个叶节点具有相等辐射度,再用于重要性采样
    • Mikula 等人的 Probability Trees
    • McCool 等人的离散函数重要性采样技术

GIBS 的简化实现:辐照度图(Irradiance Map)

由于不可能每帧为每个 Surfel 构建四叉树,GIBS 采用了更轻量的方案:

  1. 半球映射到一个四边形(Quad) ,形成一个小的 2D 辐照度方向图
  2. 每个 Surfel 维护自己的辐照度图,追踪各方向上的辐照度

存储规格:

参数配置
分辨率6×6 纹素(可配置)
每分量精度8 bits
缩放值每个 Surfel 一个 16 bit 的全局缩放因子
归一化每次迭代后对整个函数 归一化

离散函数的重要性采样算法

对任意一维离散函数

  1. 从均匀分布中采样一个随机变量
  2. 计算
  3. 从任意端开始遍历函数,逐步累加函数值
  4. 当累加值 时,当前位置即为重要性采样的结果

关键性质: 采样变量的生成概率 正比于函数值大小 —— 即光照多的方向获得更多光线

扩展到 2D

  • 6×6 的 2D 辐照度图可以被 展平为 1D 函数 处理
  • 也可以用 层级化方式 :先在 3×3 的高层做重要性采样,再在对应的 2×2 子区域中做第二步
  • 线性滤波可用于纹素交界处的插值
  • 每一步的 PDF 等于该位置的函数值 ,因此整个过程是 无偏的(Unbiased)
  • 得到的 UV 坐标通过 半球到四边形变换的逆变换 转换为光线方向

实验验证

使用 HDR 环境贴图作为测试场景,对比:

  • 横轴 :采样数量
  • 纵轴 :相对误差
场景类型余弦采样光线引导
光照集中在非法线方向收敛缓慢初始几个样本后 学习到光照方向 ,快速收敛
光照均匀且匹配余弦分布表现良好无额外优势(但也不会更差)
极小亮光源表现差同样表现差 ——6×6 分辨率太低无法精确定位

对于极小亮光源的场景,在实际游戏引擎中这些光源通常是 解析光源(Analytical Light Sources) ,会被直接采样,不依赖光线引导。


Surfel 间辐照度共享(Irradiance Sharing)

机制

  • 利用 加速结构 ,每个 Surfel 天然知道自己所在的网格单元
  • 可以访问 同一网格单元中的其他 Surfel
  • 对相邻 Surfel 之间进行 加权辐照度共享 ,跨越表面边界传播信息

效果对比(64 个样本下)

模式结果
无辐照度共享结果 斑块感严重(Blotchy) ,噪声明显
有辐照度共享仅 64 个样本即可获得 相当合理的结果
  • 室内复杂光照场景:改善极为显著
  • 室外场景:虽然理论上收敛更快,但无共享时 64 样本仍然斑块明显,开启共享后效果大幅改善

光线排序(Ray Sorting)

为什么需要排序

  • 如果光线之间 空间相干性(Spatial Coherence) 很差,GPU 性能会严重下降
  • 原因:同一个 Warp/Wave 中的线程可能遍历 加速结构的完全不同部分 ,导致 缓存利用率极差

Ray Binning 策略

  • 采用与 Battlefield V 相同的 光线分桶(Ray Binning) 方案
  • 每条光线根据 位置 + 方向 被分配到一个桶(Bin)中

Bin Index 的计算方式:

组成部分来源作用
空间哈希(主导值)Surfel 所在的网格单元坐标转为 1D 索引保证空间上相近的光线被分到一起
方向分量从该 Surfel 发射的光线编号进一步细分同一位置不同方向的光线

排序流程

  1. 第一遍 :统计每个 Bin 的光线数量和偏移量
  2. 第二遍 :生成重排序所需的索引信息
  3. 第三遍 :根据计算好的 Bin 计数和偏移量,重新排列光线

📎 详见 Battlefield V 的演讲资料。


多光源采样(Many Light Sampling)

问题背景

  • 前面讨论了如何积分光照(Integrator),现在要解决:光线命中交点后如何计算该处的直接光照
  • 压力测试场景(PvZ 地图):摄像机视锥内有 1400 盏灯光

朴素方案的瓶颈

方案适用范围问题
遍历所有光源少量光源光源数过多时完全不可行
随机采样 N 盏光源 (N ≪ 总数)数十盏光源性能极低(便宜),但光源达到数百/数千时 收敛极慢
重要性采样大规模光源需要更复杂的算法来解决收敛问题

两条最有前景的技术路线

  1. 随机光切割(Stochastic Lightcuts)
  2. 蓄水池采样(Reservoir Sampling)

随机光切割(Stochastic Lightcuts)

理论基础

  • 基于 Yuksel 等人在 HPG 2019 上发表的工作
  • 在经典 Lightcuts 基础上引入 最小化偏差的光源树采样 ,提升采样效率
  • 核心优势
    • 不需要大量样本即可收敛
    • 无需额外的空间或时间存储 (不像蓄水池重采样那样需要保存历史样本)

光源树构建(Building)

  1. 将光源位置存储在 视空间(View Space) 中(为精度考虑)
  2. 按位置的 莫顿编码(Morton Code) 对光源排序
    • 莫顿编码天然将空间上相近的光源分组,使树具有 隐式的空间相关性
    • 避免了 BVH 构建中需要的多次排序
  3. 自底向上(Bottom-Up) 构建树
    • 每个 内部节点 存储其子节点的 合并包围盒合并光照强度

光源树采样(Sampling)

  1. 选择切割(Cut) :从树中选择一条 切割线 ,切割线上的节点数由用户定义的 节点限制 控制
    • 典型值:2~8 个节点 (取决于质量等级或平台)
    • 节点数 = 最终要发射 阴影光线(Shadow Ray) 进行可见性检查的光源数量
  2. 最小化误差 :选择使 光照误差最小化 的节点来构成切割线(基于采样位置与节点的关系)
  3. 随机下行遍历 :从切割线上的每个节点出发,向下随机遍历
    • 对每个内部节点,根据 重要性权重(Importance Weights) 为其左右子节点分配概率
    • 随机选择左或右子节点
    • 最终到达叶节点,得到具体的光源

蓄水池采样(Reservoir Sampling)

理论基础

  • 基于 NVIDIA 的 ReSTIR 研究
  • 核心思想:随机评估 N 盏光源,但只选出 M 个 "赢家" 来发射光线

核心优势

特性说明
无需预计算数据结构不像 Lightcuts 需要构建光源树
每个样本仅需 1 条光线在主机平台上比 Stochastic Lightcuts 实现 更便宜

采样流程

  1. 随机采样 4~8 盏光源
  2. 对每盏光源计算 权重(Weight) ,基于:
    • 距离(Distance)
    • 光照强度(Intensity)
  3. 生成一个随机数,若该随机数小于 (当前光源权重 / 累计总权重),则 选择该光源
  4. 最终用所有采样光源的 总权重归一化结果 PDF
  5. 最终只选出 1 个赢家 发射光线

蓄水池重采样(Reservoir Resampling)的挑战

  • 为了充分发挥蓄水池采样的潜力,理想情况下应该将当前选择的样本与 空间邻域和时间邻域的样本进行比较和重采样
  • 这就是 蓄水池重采样(Reservoir Resampling / ReSTIR)
  • 但在 间接光照场景 中实现较为复杂:
    • 朴素方法需要 大量额外存储 来保存已选样本
    • 然后再与时间和空间邻域样本进行比较
  • 讲者表示这是 正在积极开发中 的功能

各方案效果对比

测试场景

  • 视野内约 700 盏灯 ,视锥外另有 700 盏灯
  • 以下对比均在仅求解 15 帧 后的间接漫反射结果
方案配置质量表现
暴力随机采样2 条阴影光线极度噪声 ,大量光照贡献缺失
蓄水池采样8 个候选样本接近收敛结果,远超随机采样,但仍有明显的 斑点和萤火虫噪声(Fireflies)
随机光切割4 个节点最接近收敛结果 ,但在主机上 计算开销更高

关键结论

  • Stochastic Lightcuts 在质量上表现最佳,但计算成本更高
  • Reservoir Sampling 在性能和质量之间取得较好平衡,尤其适合主机平台
  • 两者各有优劣,具体选择取决于 目标平台和性能预算

收敛速度

  • 从演示中可以看到,仅经过 15 帧 就能得到非常接近完全收敛的结果
  • 至此,不透明表面的方案已经完整介绍

透明物体支持(Transparency)

核心挑战

  • Surfel 非常适合为 不透明表面 缓存辐照度
  • 但 Surfel 依赖于从 G-Buffer 生成 ,而 透明物体不写入 G-Buffer ,因此同样的方法难以直接移植

解决方案:光线追踪探针(Ray Traced Probes)

  • 不再将 Surfel 附着于透明表面,而是采用 探针体积(Probe Volume) 的方式
  • 探针 持久存在 于体积中,像 Surfel 一样以光线追踪方式 收集辐射度(Gather Radiance)
  • 由于收集的是 漫反射辐射度 ,可以将其 投影到球谐空间(Spherical Harmonics, SH)
  • 使用与 Surfel 相同的 自适应 MSME 积分器 来跨帧累积探针样本

探针辐照度的帧摊分计算

  • 单帧内 无法实时计算完整的 SH 系数积分 ,因为需要大量样本才能收敛
  • 因此采用 跨帧摊分(Amortize) 策略:
    1. 每帧仅发射 少量光线 ,采样入射辐射度
    2. 将采样结果 投影到 SH 基函数
    3. 使用自适应 MSME 积分器 跨时间累积投影后的辐射度
    4. 积分器同时根据 方差 决定下一帧需要发射的光线数量

探针体积结构(RT Probes Volume Structure)

选型过程

  • 探针同样面临与 Surfel 一样的 尺度问题(Scale Problem)
  • 评估了多种方案后,最终选择了 体积裁剪图(Volume Clipmap)

Clipmap 的核心思想

  • 一组 嵌套的体积层级(Nested Volumes)
  • 每个层级覆盖 更大的区域细节更少
  • 效果:
    • 近处 :高密度探针,细节丰富
    • 远处 :低密度探针,覆盖广
    • 内存开销低
  • 不同层级可以 异步更新 ,低细节层级可以为高细节层级 预填充(Prime)

Clipmap 更新算法

当摄像机移动时:

  1. 每帧检查摄像机的世界空间位置
  2. 如果摄像机移出某层级的 中心网格 ,则将该层级的探针 朝摄像机方向平移 ,保持摄像机始终在中心
  3. 平移距离取决于摄像机偏离中心的 网格单元数
  4. 平移后产生的 新探针 使用 更高层级(更低细节)的探针插值初始化

关键优化

  • 由于层级网格覆盖范围大,大部分探针在更新后 仍然有效
  • 有效探针只需 复制到新坐标 ,而非丢弃重建
  • 这是 最大限度保留已缓存辐照度、提升性能 的关键

四层级结构可视化

  • Level 1 :最高细节,覆盖摄像机附近最小区域
  • Level 2 :中等细节
  • Level 3 :较低细节
  • Level 4 :最低细节,覆盖最大区域
  • 调试视图中:不同颜色标识像素从哪个层级采样,最高细节集中在 屏幕底部中心(摄像机近处) ,最低细节出现在 地平线(远处)

Clipmap 采样策略

朴素采样

  • 找到 包含当前像素的最高细节层级 ,直接采样该层级的 SH 系数并重建辐射度
  • 问题 :层级边界处会出现 可见的不连续跳变(Discontinuities)
  • 对于动态场景尤为严重(物体可能在某帧突然跳到低细节层级)

混合采样(Blending)

  • 为每个层级创建一个 过渡边界带(Transition Border)
  • 位于边界带内的像素同时从 当前层级相邻层级 采样
  • 根据 到边界的归一化距离 计算混合权重
  • 结果:平滑过渡,无跳变
  • 缺点 :每个着色样本需要 采样两个体积 ,开销翻倍

蓝噪声抖动采样(Blue Noise Dithered Sampling)

  • 目标:只采样一个体积 ,同时达到接近混合的质量
  • 方法:
    • 使用 蓝噪声(Blue Noise) 值(低差异分布)决定采样当前层级还是下一层级
    • 蓝噪声 易于滤波 ,与 TAA 配合良好
  • 结果:质量略低于混合方案,但 过渡平滑 ,且 性能开销仅为单次采样

动态场景表现

  • 透明物体方案在 完全动态世界 中表现良好
  • 无需任何预计算
  • 场景几何或光照变化时探针 自动更新
  • 同时能 快速收敛 到新的环境光照

帧结构与性能概览(Frame Overview)

四大阶段

阶段主要工作性能特征
1. 持久化 Surfel 工作(Persistent Surfel Work)光线追踪、辐照度累积光线追踪 主导,是最耗时的部分
2. 新生成 Surfel 工作(Spawn Work)从 G-Buffer 生成新 Surfel取决于生成数量:光线追踪几何法线重建 主导;高分辨率下 Gap Fill 可能主导
3. 滤波(Filtering)Surfel 数据滤波非常快,平均仅约 0.2 ms
4. 应用到屏幕(Apply)将 Surfel 光照写入屏幕像素光照应用 Pass(Lighting Apply) 主导

性能关键点

  • 光线追踪始终是瓶颈 ,特别是在持久化 Surfel 的工作中
  • 后续将给出 最坏情况典型游戏内容 的性能数据

压力测试设置(Stress Test Settings)

测试平台与参数

参数配置
平台PlayStation 5
输出分辨率4K
屏幕空间 Pass 分辨率1080p(输出面积的 1/4
Surfel 生成距离限制无限制(一直生成到地平线)
光线截断距离无限制
光源采样方案8 样本蓄水池采样(除非另有说明)

测试策略

  • 测试 最坏情况 :从 空场景 开始,观察收敛到可接受质量所需的时间和开销
  • 一旦收敛完成,后续开销会 显著下降 ,因此重点关注 收敛阶段(最贵阶段) 的性能

性能测试场景

场景 1:PvZ 城镇中心(仅日光)

  • 光照条件:仅太阳光
  • 收敛时间:约 3.5 秒 达到可接受质量
  • 平均耗时:约 7 毫秒
  • 注意事项:
    • 用于 GI 的 albedo 颜色与实际 albedo 纹理 不完全一致
    • 由于 绘制距离很大 ,Surfel 生成和光线追踪一直延伸到地平线

场景 2a:PvZ 1400 盏灯光压力测试(默认光线预算)

  • 光照条件:1400 盏局部光源 在视锥内
  • 收敛时间:基本不收敛 (默认光线预算不足)
  • 性能观察:
    • 相比日间场景,局部光源采样有额外开销
    • 虽然难以收敛,但系统仍在持续工作

场景 2b:PvZ 1400 盏灯光(100 万光线预算)

  • 光线预算提升至 1,000,000 条/帧
  • 收敛时间:约 10 秒 ,仍有一定噪声但在持续改善
  • 性能表现:
    • 初始生成阶段 峰值很高
    • 快速回落,但稳定后仍在 约 11 毫秒
    • 讲者承认这是需要继续优化的领域

场景 3:PvZ 1400 盏灯光(不同视角)

  • 同样 1400 盏灯光,但视角更受限
  • 收敛时间:约 7 秒
  • 性能:显著低于场景 2 ,因为视角受限意味着需要处理的 Surfel 更少

场景 3 变体:使用 4 样本 Lightcuts

  • 将采样方案从蓄水池采样切换为 4 样本 Lightcuts
  • 收敛时间:约 5 秒 (比蓄水池快)
  • 代价:平均耗时上升到约 11.3 毫秒
  • 观察:图表右侧 持久化 Surfel 和新生成 Surfel 的开销都在下降 ,方差趋于稳定

场景 4:内部 Demo 关卡(约 140 盏灯光)

  • 收敛时间:约 2 秒
  • 平均耗时:约 5.5 毫秒 ,比 PvZ 街景更便宜

自由漫游测试(Free Roam Tests)

为什么更具代表性

  • 压力测试从零开始是 最坏情况
  • 实际游戏中,玩家在关卡中移动时:
    • Surfel 会 持续生成和求解
    • 不会从零开始 (除了最开头)
    • 已缓存的 Surfel 持续提供光照

测试 1:4K 输出

指标数值
输出分辨率4K
平均耗时约 5.4 毫秒
对比压力测试性能更好

测试 2:1800p + 棋盘格渲染

指标数值
输出分辨率1800p + Checkerboard Rendering
平均耗时约 3.4 毫秒
代表性更接近实际游戏会使用的设置

Clipmap 探针开销

  • 沿与自由漫游测试相同的路线
  • 三层级 Clipmap 结构
  • 开销 非常合理 :每隔几帧 轮流更新不同层级
  • 第三层级最便宜(大部分光线为 Miss,因为覆盖远处空旷区域)
  • 如果 全屏每像素采样探针(900p):约 0.2 毫秒

未来工作(Future Work)

程序化几何支持

  • 目前 不显式支持程序化几何(Procedural Geometry)
  • 程序化几何可以工作,但会 不断生成和回收 Surfel ,因为缺乏像蒙皮网格那样的 Transform 跟踪机制

高细节几何的过度生成问题

  • 某些 高细节几何 可能导致 Surfel 过度生成(Overspawn)
  • 可选方案之一:与屏幕空间全局光照(SSGI)结合
    • 在 SSGI 效果好的区域 减少 Surfel 生成
    • 限制需要求解的 Surfel 数量
    • 限制 Surfel 和光线追踪的距离范围

光线引导的改进

  • 正在研究 跨 Surfel 共享引导信息 ,以获得更全面的光照方向认知
  • 正在研究使用 ReSTIR 类方法 来增强光线引导

多光源采样的优化方向

优化方向说明
光源可见性存储在网格单元或体素数据结构中存储光源可见性,大幅减少每次光线命中需考虑的光源数量
光线间共享光源由于光线已按空间排序(Ray Binning),同一 Bin 内的光线可以 共享光源采样结果
蓄水池空间采样利用排序后的光线进行空间蓄水池采样
时间蓄水池采样将蓄水池存储在 网格单元结构或每个 Surfel 上
Lightcuts 遍历优化当前实现未充分利用 平台特定指令(Platform-Specific Intrinsics)
光源采样调度将光源采样从光追 Pass 中移出,将二次阴影光线调度到后续 Pass

探针系统的未来方向

  • 探针 Clipmap 方案仍处于 早期阶段
  • 计划添加:
    • 光线引导 支持
    • 高光(Specular) 支持
  • 计划通过 与 Surfel 光线调度共享和整合光线 来提升性能

总结(Wrap Up)

GIBS 技术的核心价值

  1. 场景的机会性 Surfel 化 提供了高效的 表面信息缓存机制
  2. 缓存机制具有三大特性:
    • 持久化(Persistent) :跨帧保留,不因离开屏幕而丢失
    • 全动态(Dynamic) :支持蒙皮角色、动态物体、动态光源
    • 分辨率解耦(Decoupled from Output Resolution) :性能与输出分辨率无关
  3. 使用 Surfel 在 各种几何体和场景 上缓存辐照度
  4. 对于不适合 Surfel 的几何体(如透明物体),提供 探针 Clipmap 回退方案

性能总结

场景类型典型耗时
大型室外(仅日光)~7 ms
1400 灯压力测试~11 ms
中等灯光(~140)~5.5 ms
自由漫游(4K)~5.4 ms
自由漫游(1800p + CB)~3.4 ms
探针采样(全屏 900p)~0.2 ms