Automatic Sampling for Discontinuities in Differentiable Shaders
University of California San Diego; Adobe Research; Reve
一句话总结
面向可微渲染中”不连续函数积分求导”的老问题,本文提出一套全自动边界采样方法:把任意含 if-else 分支的着色器程序编译成一个”分段常值代理程序”,再用线段吸附(segment snapping)在积分域中随机撒线段、比较两端是否跨越边界来定位不连续,从而无需为每类边界手写专用采样例程,就能对多边形、椭圆、贝塞尔曲线乃至神经网络、噪声等隐式边界统一求导。该工作获 SIGGRAPH Asia 2025 最佳论文奖。
研究背景
图形、视觉与机器学习中大量逆问题都归结为对含参积分求导 \(\nabla_\theta \int_\Omega f(x,\theta)\,dx\)。当被积函数 \(f\) 不连续时,标准自动微分会给出错误结果——它忽略了微分阶跃不连续时出现的 Dirac delta 分布,而这一项需要在不连续边界上积分,称为边界积分。
现有方法可归为两类,各有硬伤:
- 边界采样法(如 Li et al. 的边采样、DiffVG)直接在决策边界上撒点求解边界积分,等样本数下精度高,但都要求能显式参数化并采样边界。当边界复杂(无法显式表达)时,往往需要为特定问题手写专用采样例程,非常繁琐且经常”定义不良”。
- 面积采样法(重参数化 / warped-area sampling、A-\(\delta\) 等)借助速度场与散度定理把边界积分转回原始区域,从而无需边界采样,但常伴随高方差(有时甚至无穷方差),或在网格采样频率低于不连续频率时产生显著梯度偏差。
本文的立场:做一个”开箱即用”的通用自动微分方法,只要决策边界本身可微,就能自动处理不连续,既保留边界采样的低方差与高精度,又摆脱对专用采样例程的依赖。方法聚焦于低维积分(2D 或 3D)。
方法
整体建立在两个环环相扣的核心组件上:一是把分段连续着色器编译成分段常值的代理着色器;二是在此代理上用线段吸附做自动边界检测。随后依次完成分支索引归属、概率密度估计、两侧被积值评估与边界速度计算,最终在一次反向传播中输出边界导数。
flowchart TD
A[输入: 含 Disc if-else 的着色器程序] --> B[编译期程序变换<br/>转成分段常值代理 f_pc]
B --> C[在积分域随机撒线段<br/>比较两端 f_pc 是否不同]
C --> D[二分搜索定位边界点]
D --> E[分支索引归属<br/>取 |g_i| 最小的分支]
E --> F[核密度估计采样概率 p]
E --> G[两侧被积值 f x+ 与 f x-]
E --> H[隐函数定理算边界速度]
F --> I[单次反向传播<br/>输出边界导数]
G --> I
H --> I
问题设定。 被积函数写作有向无环图 \(G=(V,E)\),不连续以 if-else 表达。分支算子为
\[B(x,\theta)=\begin{cases} h_+(x,\theta) & \text{if } g(x,\theta)>0 \\ h_-(x,\theta) & \text{otherwise}\end{cases}\]
其中标量前驱 \(g\) 称为边界函数,不连续位于其零水平集 \(g(x,\theta)=0\)。要求 \(g\) 几乎处处可微且 \(\lVert \partial_x g\rVert>0\)(即 \(g\) 子图中不含分支算子),从而其零水平集在 2D 中构成闭曲线、3D 中构成闭曲面。\(h_\pm\) 无此限制,可任意嵌套。由 Reynolds 输运定理,梯度分两项:
\[\nabla_\theta I = \int_\Omega \nabla_\theta f(x;\theta)\,dx + \partial_\theta I_b\]
前者是内部项,标准自动微分即可;后者是边界项
\[\partial_\theta I_b = \int_{\partial\Omega}\big(f(x^+,\theta)-f(x^-,\theta)\big)\,\partial_\theta x^\perp\, dx\]
关键设计 1:分段常值代理。 检测不连续的根本困难在于——函数值变化既可能来自连续变化、也可能来自不连续跨越,仅看函数值无法区分。作者对 \(f\) 做一次”图着色”式的源码变换,得到分段常值代理 \(f_{pc}\):它保留原图结构(即不连续曲线 \(\partial\Omega\)),但消除所有连续变化,并保证相邻区域拥有唯一标识。设有 \(m\) 个分支算子,\(f_{pc}(x)\) 用一个三值状态向量 \(s_x=(s_i)_{i=1}^m\) 表示,每个分量取值为:\(\times\)(该分支未被执行)、\(0\)(谓词为真)、\(1\)(谓词为假)。单次前向即可填充该向量,代价与分支数 \(m\) 线性相关,而非像 A-\(\delta\) 那样枚举所有分支(指数级)。每个连续区域由一个三进制整数唯一编码。
关键设计 2:线段吸附采样边界。 在代理 \(f_{pc}\) 上做点采样即可可靠检测边界:初始化时在网格上撒分层抖动点作为线段一端,再沿随机方向取固定长度得到另一端。对每条线段评估两端 \(f_{pc}\),若不同则说明跨越了边界,再对该线段做二分搜索(通常约 15 次,宽度缩小 \(2^{-15}\))精确定位边界点;若两端相同则丢弃该线段(可能漏采细窄区域,但实践中影响不大)。这一步既省去专用采样例程,也自然获得图像空间中的边界样本。
关键设计 3:分支索引归属。 每个边界点须归到某个分支算子 \(B_i\) 才能求边界速度、估密度、取两侧值。由于浮点精度与有限二分步数,点不会精确落在 \(g_i=0\) 上,故取函数评估路径上使 \(|g_i(x;\theta)|\) 最小的分支索引 \(i\)。此过程只检验实际经过的分支(不评估未走到的 \(g_i\)),并顺带把 \(g_i\) 值留在自动微分计算图中,供后续求边界速度。
关键设计 4:概率密度估计。 线段吸附得到的边界点分布一般非均匀,用 \(k\) 近邻核密度估计校正:2D 情形下 \(p(x)=\dfrac{k}{n}\dfrac{1}{2R_k}\),其中 \(R_k\) 是到第 \(k\) 个近邻的距离。该估计有偏但一致。
关键设计 5:两侧被积值的精确评估。 以往做法沿法向偏移 \(\epsilon\) 取 \(x^+,x^-\) 两点分别评估,在高曲率或被积函数急剧变化处不准。本文再做一次程序变换:给函数额外传入 \(\text{sign}\in\{+,-\}\),强制指定分支算子走对应路径(覆盖其条件判断),从而恰在边界点上精确评估两侧的 \(f(x^+)\) 与 \(f(x^-)\)。
边界速度与最终导数。 由隐函数定理,边界速度为
\[\partial_\theta x^\perp = -\frac{\partial_\theta g_i(x)}{\lVert \partial_x g_i(x)\rVert}\]
为避免对每个分支单独做反向传播,实现上只计算 \(g_i(x)/\lVert\partial_x g_i(x)\rVert\)、把分子 \(g_i(x)\) 留作未微分项(\(\partial_x g_i\) 用前向模式自动微分算),再对下式做单次反向传播同时得到全部参数分量的边界导数:
\[\partial_\theta I_b = -\,\mathrm{AD}_\theta\left\{\sum_{i=1}^{n} \frac{\big(f(x_i^+,\theta)-f(x_i^-,\theta)\big)}{p_i}\frac{g_i(x_i)}{\lVert\partial_x g_i(x_i)\rVert}\right\}\]
为保证正确,只让梯度沿 \(g_i(x_i)\) 回传(微分后得 \(\partial_\theta g_i\)),其余项 detach。
实现。 编译器基于 SLANG.D,新增 [Disc] 标签标记不连续的 if-else;程序变换只需两次 DAG 遍历,平均约 30ms,编译时间随分支数线性增长。线段吸附、核密度估计、边界导数与优化循环用 PyTorch 实现,通过自定义 autograd 函数与 SLANG.D 的前/反向子程序互操作。全局设 \(k=14\)、二分迭代 15 次。
实验结果
与既有边界导数方法对比。 在简单圆的半径导数(解析值 \(\partial_r I_b=-2\pi r\approx -2.51\))上,各方法都准确。但对没有显式采样例程的复杂形状,模糊法偏差明显、WAS 因边界复杂导致速度场剧变而方差极高(如给出 \(-0.150\pm 3.52\)),而本文与 A-\(\delta\) 都能给出高质量导数。在低采样率下的两个硬案例——多条相邻不连续、边界附近有高频连续变化——面积采样法会给出错误符号或零导数,本文因直接采样边界而稳健正确。
A-\(\delta\) 的扩展性瓶颈。 绘画风格渲染中,A-\(\delta\) 编译器不适合大量不连续语句,超过 200 个圆盘即超时;本文编译只需两次 DAG 遍历、与图元数无关(约 30ms),配合规则网格加速结构,2000 个圆约 90 秒。棋盘格实验(用两棵二叉树表示)显示:本文运行时随树深线性增长、A-\(\delta\) 因评估所有分支而指数增长并在 \(512^2\) 采样时耗尽内存;本文的导数随采样数持续收敛到真值。
广泛应用。 方法解锁了此前难以实现的一系列应用:
- 二值函数拟合(双线性插值网格 + 阈值),保持目标锐利不连续,优于 ReLU / sigmoid 等连续激活的模糊结果;可扩展到 2D 扫掠面、3D 缠绕数场、CSG 树几何恢复。
- 非真实感渲染:Voronoi 马赛克(含 Perlin 噪声扭曲边界)、绘画风格渲染(支持椭圆、多边形、贝塞尔曲线乃至噪声形变圆)、cel 卡通着色(自动对 cel 阈值与光源位置求导)。
- 可微光线步进:直接微分含任意可微隐式几何(不限于 SDF)的 ray-marching 循环,从多视图恢复高亏格几何。
- 可微 3D 光栅化:三角网格(数十万三角形)、3D 椭球(不同于 3D Gaussian,边界处不透明度突降为零,保证几何导数纯来自不连续),并用于阴影艺术、逆扫掠面、不连续纹理优化(如地球陆地/水体边界,支持语义化编辑)。
其他性质与消融。 因在图像空间检测不连续,方法天然感知遮挡——分段常值代理会自动剔除被遮挡的边界,只采样可见部分;相比之下 DiffVG 先选物体再选边界点,会在大量遮挡场景产生稀疏导数。超参消融表明:导数误差随样本数收敛;二分迭代 10–15 次即足够;核密度估计在 \(10 亮点: 局限: 本文把”检测不连续”这一难点巧妙地转化为一个可离散判定的问题:只要能把连续变化剥离成分段常值,跨越边界就变成”两端标识是否相同”的确定性比较,从而摆脱了对边界解析形式的依赖。这条思路的普适性很强——它提示我们,很多”难采样”的几何问题也许可以先做一次保结构的离散化变换,再用简单的随机探测去定位。 作者指出的两个后续方向尤其自然:其一,用近期基于射线投射或 MCMC 的水平集均匀采样替代线段吸附,可省去核密度估计这一有偏环节;其二,把程序变换推广到含随机数播种的着色器,将解锁蒙特卡洛路径追踪等更广的应用。此外,占据式 3D 椭球光栅化与 3D Gaussian Splatting 的对照也颇具启发:当几何导数被设计为”纯粹来自不连续”时,几何参数的优化不再依赖连续的不透明度衰减,这为重新审视基于泼溅的可微渲染提供了一个干净的分析视角。亮点与局限
[Disc] if 表达”的假设。延伸思考