DiffCSG: Differentiable CSG via Rasterization
The University of Edinburgh; Inria; Microsoft Research Asia; Nanjing University; University College London
一句话总结
DiffCSG 把经典的 CSG 光栅化算法(Goldfeather)搬进可微渲染管线,通过显式检测并抗锯齿处理”图元交线”,让布尔运算结果对图元连续参数可微,从而用图像损失反向优化 CAD 模型参数,且比基于 SDF 的方法快约三个数量级。
研究背景
构造实体几何(CSG)用参数化图元(圆柱、立方体、球、草图拉伸等)加布尔算子(并、交、差)来表达 3D 形状,是 OpenSCAD、Fusion360 等 CAD 软件的核心建模范式。它的优势是形状可编辑、尺寸可复用,但复用一个既有设计往往要面对大量彼此难以直观关联的参数,手工调参是繁琐的试错过程。
可微渲染是近年来反演优化的利器:只要每个场景参数经由可微操作影响像素值,就能用图像损失把参数梯度反传回去。问题在于现有可微渲染器都不适合 CSG:
- 基于网格的快速可微光栅化(如 Nvdiffrast)要求先把布尔运算算成显式网格。而网格布尔运算复杂、昂贵,且每次参数变化都会改变结果网格的拓扑(顶点数、连接关系),既难在自动微分框架里实现,又要在每步优化重新执行。
- 基于 SDF 的方法能把布尔运算写成 min/max(softmax 平滑)从而可微,但需要为每类图元解析地定义 SDF(复杂图元如贝塞尔扫掠面极难写),且体素级采样与球面追踪渲染代价高昂。
本文的核心 idea:既用网格表示图元(任何有固定三角化的图元都能支持),又不显式计算网格布尔运算——转而复活 CSG 光栅化,用深度测试与奇偶(parity)测试直接”显示”布尔结果,同时保留原始图元的三角网格,这样梯度就能从像素反传到图元顶点,再到控制顶点的图元参数。
方法
整体框架是在标准可微光栅化管线(浅蓝色部分)上做两处关键改造。
flowchart LR
A[CSG 模型<br/>参数化图元+布尔算子] --> B[Goldfeather 光栅化<br/>用深度+奇偶测试替代深度测试]
A --> C[交线检测<br/>图元间三角形求交]
B --> D[抗锯齿模块<br/>可见性边 + 交线一起送入]
C --> D
D --> E[着色输出图像]
E -. 反向传播 .-> A
关键设计 1:用 Goldfeather 算法替代深度测试。 Goldfeather 只需在光栅化时把普通深度测试换成”深度+奇偶测试”,就能实现布尔运算而不改动图元网格。以两个凸图元 \(A\)、\(B\) 为例:交集 \(A\cap B\) 只保留被奇数个多边形遮挡的正面片元;差集 \(B-A\) 保留 \(A\) 中被 \(B\) 遮挡奇数次的背面片元、以及 \(B\) 中被 \(A\) 遮挡偶数次的正面片元;并集则退化为普通深度测试。这样无需生成新网格即可渲染布尔结果。
关键设计 2:显式检测并抗锯齿交线。 Goldfeather 渲染会在图元相交处产生原始几何里不存在的不连续边,这些边往往不在物体轮廓上、也不对齐输入网格边,导致标准可微光栅化(只对输入网格的可见性/轮廓边抗锯齿)在这里拿不到有效梯度。而图元相交恰恰是随参数变化最剧烈的视觉特征。作者的做法是:遍历不同图元间的所有三角形对,把交线表示成三角形顶点的函数(用 PyTorch 并行计算,天然可微),再用 OpenGL 带深度测试渲染出被交线穿过的像素,最后把这些像素连同交线端点一起送入抗锯齿模块做像素混合——与轮廓边同样处理。虽然网格布尔运算很难,但”只检测交线”是容易且可并行的任务。
关键设计 3:像素混合的可微抗锯齿。 抗锯齿沿用 Nvdiffrast 的思路并扩展到交线:对被交线 \((p,q)\) 穿过的相邻像素 \(A\)、\(B\),按边对像素中心连线的覆盖情况做颜色线性混合,如 \(\text{Color}^{B}_{\text{after}} = \alpha\,\text{Color}^A + (1-\alpha)\,\text{Color}^B_{\text{before}}\),混合权重 \(\alpha\) 是交点位置的线性函数(从中点处的 0 到像素中心处的 0.5)。由于混合是交线端点的函数、端点又是图元顶点的函数,梯度得以经自动微分从像素一路反传到图元顶点。
关键设计 4:顶点到参数的反传。 为避免逐图元繁琐地把每个顶点写成参数函数,作者用内在缩放因子把顶点绑定到参数(如锥形圆柱的半径/高度对应顶点位置的水平/垂直缩放),外在参数(位置、朝向、整体缩放)则表达为额外变换矩阵;贝塞尔草图拉伸这类图元则用控制点的多项式表达顶点。图元采用较粗的三角化,以效率优先于表面光滑度。
优化目标为多视图图像损失 \(\arg\min_{\{\theta_i\}} \|I(\{\theta_i\}, p_{cam}) - I_{target}\|\),可用 \(L_1\) 或 \(L_2\);实现基于 PyTorch + Adam,学习率 \(10^{-3}\),损失阈值 \(5\times10^{-4}\),最多 5000 步,分辨率 512×512。目标图像可用逐像素法向或图元纯色。
实验结果
在 50 个 CSG 模型(共 300 个测试样例)的基准上,对默认参数施加随机扰动得到源形状,再优化回默认形状。运行时间分布与代表性形状单次迭代耗时如下:
| 场景 | 三角形数 | 参数数 | Goldfeather | 交线检测 | 优化 | 单步总耗时 |
|---|---|---|---|---|---|---|
| 自行车 | 2980 | 17 | 0.167 s | 0.072 s | 0.106 s | 0.345 s |
| 赛车 | 4336 | 22 | 0.163 s | 0.150 s | 0.244 s | 0.557 s |
| 月亮 | 128 | 3 | 0.019 s | 0.014 s | 0.028 s | 0.061 s |
| 螺母 | 88 | 16 | 0.022 s | 0.012 s | 0.026 s | 0.060 s |
整体上 62% 的形状可在 10 秒内拟合完成,29% 在 100 秒内,仅约 9% 的复杂形状需要 1 分钟以上(不超过 20 分钟)。与基于 SDF 的 UCSG-Net 相比,本方法快约三个数量级(在多个例子上耗时从上千秒降到几十秒),达到相近的 Chamfer 距离,且在 SDF 方法失败的挖方孔案例上仍能成功——原因是渲染式方法只需二次复杂度的屏幕采样,而 SDF 需在 3D 空间做三次复杂度的密集采样。与无梯度方法 CMA-ES 相比,后者只能处理少参数简单形状。
亮点与局限
亮点:
- 巧妙地把老算法(Goldfeather CSG 光栅化)与新范式(可微光栅化)嫁接,回避了网格布尔运算这一最难的环节。
- “只检测交线并抗锯齿”这一关键洞察,用一个可并行、可微的轻量步骤补齐了图元相交处缺失的梯度;消融实验显示:不做交线抗锯齿时,只有交线才携带信息的场景优化会完全卡在初始状态。
- 简单、快速、易于接入现代机器学习框架(直接集成到 Nvdiffrast),支持球、圆柱(含锥度)、立方体、草图拉伸等常见图元。
- 支持直接 3D 编辑(编辑导出网格后反解参数)与图像编辑(在渲染图上涂改后反解参数)等下游应用。
局限:
- 图元消失不可逆:某参数(如半径)被优化到 0 会导致图元消失,而方法依赖可见像素取梯度,一旦消失便无法把该图元再拉回优化(可加正则约束,但有时消失冗余图元反而是想要的)。
- 目标形状过远易失败:源与目标差距太大时优化可能失败(如图像编辑需保证源/目标的孔洞有重叠优化才能推进)。
- 参数化方案影响优化:把可编辑参数抽象成少量超参数更易优化;共享参数化能让顶栏跟随椅背移动,独立参数化则可能让顶栏消失而非移动到目标。
- Goldfeather 与交线检测的实现尚未优化,仍有提速空间;内部信号方面,插值顶点法向对曲面提供更丰富信号,但对大片同朝向的分片平面无济于事。
延伸思考
- 本文只优化连续参数、假定 CSG 离散结构已知。一个自然方向是与迭代式程序综合结合,联合求解离散结构(图元数量/类型、布尔算子类型)与连续参数。
- “图元消失不可逆”本质是可见性驱动梯度的通病,与高斯泼溅等表示中”消失的基元难以复活”的问题同源,或可借鉴周期性重生/克隆等机制。
- 方法对图元的唯一要求是”有固定三角化”,理论上可扩展到更复杂的参数曲面(NURBS、扫掠面),把交线检测推广到曲面片求交将是关键难点。
- 交线检测采用三角形对暴力求交(二次复杂度),对高三角形数场景是潜在瓶颈,用空间加速结构剪枝会是实用改进。