image-20260721084427797

概括:1 spp +1-2次反射 + 1次神经网络推理 = 100+ spp + 10-20次反射

推理

系统为每个像素物理追踪极短路径(通常 1-2 次反射)。在终点处,物理计算仅获取该点的直接光照,而后续所有反复反射所贡献的间接光照,全部由神经网络(神经缓存)通过一次前向传播推理生成。

输入

参数 编码方式 维度
位置 x 频率编码(12组正弦) 36
散射方向 ω One-Blob(4个核 × 球面坐标) 8
表面法线 n One-Blob(4个核 × 球面坐标) 8
粗糙度 r One-Blob(1−e−r1−e−r 变换,4核) 4
漫反射 α 原始 RGB(不解码) 3
镜面反射 β 原始 RGB(不解码) 3
填充(Padding) 常数 11(替代偏置项) 2

输出

3 维浮点数(RGB):神经网络的全连接层(7层,5层隐藏层各64神经元)最终输出 3 个通道

着色:

直接光照:完整 BRDF 积分 + 多光源采样,使用 ReSTIR 加速采样

间接光照(第一/二次弹射):只算单个方向的 BRDF 值

$f_r = \frac{D \times G \times F}{4 \times (N \cdot L) \times (N \cdot V)} $

image-20260721084455926 image-20260721084512189

当光线束的面积>c⋅a0(像素面积的 1%)切换到神经网络(光线已经散开了,人眼比较难分辨,玻璃p较大,粗糙表面p较小)

image-20260721084545891

间接光照(后续无限弹射):神经网络推理值

最终像素颜色 = 直接光照(物理计算) + 间接光照(神经网络预测)

训练

网络通过观察“不同位置、不同方向”的成千上万个单点值,自动学到了“这个空间里,哪个方向的散射光强、哪个弱”的分布规律。这跟用几千个样本做蒙特卡洛积分去逼近真实积分,在数学本质上是同构的——只是把“运行时累加”换成了“训练时梯度累加”

训练路径

实时训练——从短的渲染路径中,随机选取一小部分(通常少于3%),为它们额外扩展几个顶点作为“训练后缀”。在这些更长的训练路径的每一个顶点上,收集辐射度估计值。训练的目标值不是通过路径追踪得到的无偏渲染值,而是由神经辐射缓存自己的预测值提供的,从而在实时动态场景中提供足够的训练数据。

真实辐射值注入

保留了训练路径中1/16的完全无偏训练路径,通过俄罗斯轮盘赌(也就不是前面的面积启发式)终止来定期注入真实辐射值。

这 1/16 的无偏后缀追踪得到的含噪辐射度值,并不用于显示,而是作为“锚点标签”喂给神经网络进行梯度下降训练。

EMA

为了抑制因激进优化带来的时间性伪影(如闪烁),对优化过程中产生的网络权重应用EMA。用于渲染查询的权重是平滑后的权重,而非原始优化权重。

BottleNeck

访存:论文设计的网络非常(仅 64 个神经元宽),矩阵乘法本身很小,计算量(O(width2))本身并不大。然而,每一层运算依然需要从显存中读取权重矩阵。

优化:将整个网络写成一个单一的 GPU 内核(Kernel),而不是像 TensorFlow 那样拆分多个内核调用。将整个网络中间层的激活值(64×128)全部塞进 GPU 的共享内存,把权重矩阵塞进寄存器。