跳转到内容

redner — 让光线追踪能反向传播过几何边缘

是什么

redner 是 2018 年 MIT 的 Tzu-Mao Li 等人做的可微路径追踪器——你给它一张照片,它能反向告诉你「场景里那个椅子腿应该往左移 0.3mm,颜色再红一点」,自动算出梯度让你用 SGD 调形状、材质、光源。

日常类比:普通渲染器是「输入场景 → 输出图片」的单向相机。redner 是一台会反向推的相机:你给它一张目标图,它能算出「为了让我拍出这张图,场景里每一个三角形该怎么动」。

最关键的一行:它是第一个能正确反向传播过几何遮挡边缘的 Monte Carlo 渲染器

为什么重要

不理解 redner 解决的问题,下面这些事会让你困惑:

  • 为什么 PyTorch 直接搭一个光线追踪器、求梯度,结果梯度永远是 0——明明场景在动
  • 为什么 NeRF(2020)用体积渲染而不是表面渲染——它绕开了 redner 死磕的那个问题
  • 为什么「从一张照片反推 3D 场景」(inverse rendering)在 2018 之前一直做不准
  • 为什么材质识别 / 光源估计 / 形状重建在 redner 之后突然能用 SGD 端到端训了

redner 之前,大家用 rasterization-based 的近似可微渲染器(OpenDR 2014、Soft Rasterizer 2019),梯度不准但能跑。redner 第一次把「物理正确的可微」做出来。

核心要点

一句话核心问题

几何遮挡(visibility)会让像素颜色对场景参数产生”阶跃式”变化——梯度处处为 0,但在边界上是 ∞。Monte Carlo 采样直接求这种积分的方差是无穷大,完全没法反向传播

用日常场景理解

想象你拿手电筒照墙,墙上有个圆盘投出的影子。问:「如果圆盘往右移 1mm,影子里某个点 P 的亮度怎么变?」

  • 如果 P 一直在影子里 → 亮度不变,梯度 = 0
  • 如果 P 一直在影子外 → 亮度不变,梯度 = 0
  • 如果 P 正好在影子边缘——亮度从 0 跳到 1,梯度 = ∞

整张图的总梯度,全部来自那条细如发丝的边界线。普通 Monte Carlo 在面积上随机撒点,撒到边界的概率是 0,所以永远抓不到梯度

redner 的三个发明

  1. 边缘采样(edge sampling):不再随机撒面积积分点,而是显式枚举三角形的轮廓边(silhouette edges),在边上专门撒采样点。这是把 Reynolds transport theorem 用到渲染里——把面积积分的导数拆成「内部光滑部分 + 边界部分」。

  2. 次级边可见性测试:直接边在镜头里看到的边好枚举,但间接光照里也有遮挡——比如墙上反射出影子。redner 处理这种间接边,用一个层次结构 + 重要性采样加速。

  3. embree + autodiff 集成:用 Intel embree 做光线求交,外面套上 PyTorch 的反向传播,让整个 pipeline 既快又能 grad

实践案例

案例 1:从一张照片反推材质

输入:一张茶壶照片 + 已知茶壶 3D 网格 未知:茶壶表面是什么材质(漫反射 / 金属 / 粗糙度)

material = redner.Material(diffuse_reflectance=torch.tensor([0.5, 0.5, 0.5], requires_grad=True))
for step in range(200):
rendered = redner.render(scene, material)
loss = ((rendered - target_photo) ** 2).mean()
loss.backward()
optimizer.step()

200 步后,material.diffuse_reflectance 收敛到正确颜色。没有 redner,第三行 loss.backward() 在边缘像素那里梯度就废了

案例 2:从照片反推几何形状

更难——形状变了,遮挡也变,几何边在反向传播里出现。redner 的边缘采样在这里发力:

输入:单视图照片 优化:mesh vertex 坐标 输出:拟合出 3D 网格

这是 redner 论文 Figure 14 的实验,初代用 SGD 反推几何的工作之一。

案例 3:和 NeRF 的关系

NeRF(Mildenhall 2020)是另一条路:避开表面渲染,用体积渲染(每条光线沿路积分密度)。

  • redner:表面渲染 + 显式处理遮挡边
  • NeRF:体积渲染(连续函数),没有遮挡边这个问题

NeRF 拿掉了 visibility discontinuity 难题,代价是每个场景都要从头训练一个网络。redner 是显式几何 + 物理材质,支持编辑。两条路并存——表面派(redner / Mitsuba 3)做 inverse rendering,体积派(NeRF / 3DGS)做 novel view synthesis。

踩过的坑

  1. 边缘枚举非常贵:每个三角形要测试是否是 silhouette edge(背面 / 正面交界),N 个三角形 O(N²) 边对。redner 用 BVH 加速,但百万面级场景仍然慢。后续 Mitsuba 3(2022)用更好的算法。

  2. 次级边采样的方差仍然大:直接边好搞,间接边(光在场景里反弹后才碰到的遮挡)需要很多采样点才能稳定,调参不当梯度噪声大、训练不收敛

  3. 不能处理透明/折射的 visibility:redner 假设硬表面遮挡。玻璃、烟雾、毛发这些「软遮挡」需要后续工作(reparameterization 2020、path-space differentiable rendering 2020)。

  4. 必须有正确的 3D mesh 起点:redner 优化的是已知拓扑的 mesh 顶点。拓扑变化(开个洞、加个把手)超出能力,需要 differentiable mesh evolution(Mesh R-CNN / DMTet)。

适用 vs 不适用场景

适用

  • 已知 3D 几何 + 反推材质 / 光源 / 纹理
  • 已知拓扑 + 反推顶点位置(小幅变形)
  • 物理正确性要求高的逆问题(科研 / VFX)
  • 想保留可编辑显式几何的下游应用

不适用

  • 拓扑未知 + 大变形 → 用 NeRF / 3D Gaussian Splatting
  • 实时渲染 → redner 是离线的,单帧秒级
  • 软遮挡(透明 / 烟雾)→ 用后续 differentiable volumetric 方法
  • 端到端从图像生成场景(无几何先验)→ 用 diffusion + 3D 重建

历史定位

  • 2014:OpenDR——第一个可微渲染器,但用 rasterization + 局部线性近似,梯度不准
  • 2018redner——第一个 Monte Carlo + 物理正确的可微渲染器
  • 2019:Soft Rasterizer——把 rasterization 软化以避开离散性,速度快但仍是近似
  • 2020:NeRF——绕开 surface visibility,用 volume rendering
  • 2020:Loubet 的 reparameterization——更通用的处理 discontinuity 方法
  • 2022:Mitsuba 3——把可微渲染做成工业级框架,吸收 redner / Loubet 思想
  • 2023:3D Gaussian Splatting——用各向异性高斯替代体素,速度上量级提升

redner 是这条线的理论奠基:之后所有 surface-based 可微渲染都在它的边缘采样框架上扩展。

学到什么

  1. 不连续函数的”期望梯度”不等于”梯度的期望”——遇到 visibility / argmax / step function 时,普通 autodiff 会静默给错答案(梯度 = 0),不是报错
  2. 边界积分是处理这类问题的通用工具——把面积积分的微分拆成「内部光滑 + 边界跳跃」,在边界上单独采样
  3. 物理正确 vs 近似可微是工程上要权衡的——redner 选了前者,速度慢但梯度准;Soft Rasterizer 选了后者,反过来
  4. 可微渲染开辟了”用 SGD 优化 3D 场景”的新范式,是 NeRF / 3DGS / 神经辐射场整套革命的前奏
  5. 同一个数学陷阱在多个领域反复出现:argmax 在分类、attention 中的硬选择、采样在 RL 中——任何”离散决定”都会让梯度断流,处理思路都是「把硬变软」或「在边界单独算」

延伸阅读

关联

  • 3d-gaussian-splatting —— 同样追求”可微 3D”,但走 volume + 高斯路线,绕开 visibility 难题
  • pytorch —— redner 的 autodiff 后端
  • jax —— 后来 Mitsuba 3 也支持 JAX 后端,思路一脉相承
  • attention —— attention 把 argmax(硬选)软化成 softmax,让梯度能流过,是同一类”软化离散”思路的语言模型版本

关键启发

  • 当一个 pipeline 看起来「明明能跑、但 SGD 不收敛」时,先检查有没有离散决策点让梯度断流——很多深度学习架构的进步本质上是「把某个硬决策软化」
  • 物理正确不是奢侈品——近似可微在简单场景能用,但复杂遮挡下近似误差会让优化收敛到错答案,redner 的边缘采样是这种场景下唯一靠谱的路

反向链接

  • 3d-gaussian-splatting —— 3D Gaussian Splatting — 用一堆 3D 模糊光斑重建场景
  • attention —— Attention Is All You Need
  • jax —— JAX — Google 函数式数值计算
  • pytorch —— PyTorch — 深度学习主流框架