Differentiable Block Worlds 论文可视化走读:用 Rerun 观察超二次曲面 3D 场景分解的优化过程
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
导读
从一组带相机姿态的图片出发,恢复出"由若干可解释几何基元组成的带纹理 3D 场景",是三维重建中极具挑战性的优化问题。本文以 Rerun 开源仓库中的differentiable_blocks_world示例(README)为主线,逐层拆解论文Differentiable Block Worlds: Qualitative 3D Decomposition by Rendering Primitives的核心机制:场景如何用背景球体、地面平面与超二次曲面(superquadrics)表示、优化为何只能删减基元而不能新增、透明度(opacity)如何被当作可优化参数来控制网格数量、以及三阶段优化策略如何稳定收敛。读完本文,你将掌握该论文的方法脉络,并理解 Rerun 的Mesh3D、Pinhole、Opacity等类型如何支撑这类"优化过程可视化"的落地。
一、示例定位:一份"可视化走读"而非普通 Demo
在 examples/manifest.toml 中,该示例被归入3d-reconstruction(3D 重建与建模)类别,与structure_from_motion、instant_splat、glomap等示例并列,标题为 "Differentiable blocks world: qualitative 3D decomposition by rendering primitives",标签为3D、Mesh、Pinhole camera、Paper walkthrough。
与仓库内大多数"运行即出图"的示例不同,这是一个典型的paper walkthrough(论文可视化走读)示例:它本身不含独立可运行的示例代码,而是由作者修改原始研究源码、在关键位置埋入 Rerun SDK 的日志调用后,把优化过程中每一帧的场景状态记录下来,形成一系列可交互回放的可视化(README 中配有 overview 与多个阶段演示的动画/视频链接)。从源码结构看,该示例目录下仅有README.md一个文件(见 examples/python/differentiable_blocks_world),其元数据中的source字段指向外部研究仓库,因此它在本仓库中的角色是"方法讲解 + 可视化成果展示"而非开箱即用的脚本。
二、问题背景:从多视图图像到可解释的 3D 分解
Finding a textured mesh decomposition from a collection of posed images is a very challenging optimization problem.
论文要解决的问题是:给定一组带姿态(posed)的图像,重建一个"带纹理的网格分解"(textured mesh decomposition)——即场景不是被表示成一整张网格,而是被拆解为若干个语义上可解释的部分。这种分解比单纯的稠密重建更困难,因为它同时要求:
- 几何拟合:每个部分都要能解释观测图像中对应区域的几何形状;
- 纹理拟合:每个部分的表面纹理要与多视角观测一致;
- 结构可解释性:分解结果要由少量、清晰的基元组成,而不是无结构的点云或单一 mesh。
论文Differentiable Block Worlds由 Tom Monnier、Jake Austin、Angjoo Kanazawa、Alexei A. Efros、Mathieu Aubry 等人提出,其核心思路是用可微分渲染(differentiable rendering)把"场景表示 → 图像合成"整条链路变成可反向传播的优化管线:以几何参数为优化变量,让渲染出来的图像尽可能接近真实观测,从而同时求解形状与纹理。
三、场景的几何表示:icosphere 背景 + 地面 + 超二次曲面
README 明确指出,该优化场景由三部分构成:
- 背景 icosphere(二十面体细分球):用于表示场景中无法用前景基元解释的背景区域,通常承载天空/远景的环境纹理;
- 地面平面(ground plane):承载地面区域的纹理,为场景提供明确的支撑面结构;
- 多个超二次曲面(superquadrics):作为前景"积木块(blocks)",每个 block 是一类可由参数方程描述的柔性二次曲面族,通过调整形状参数可以退化为球体、立方体、圆柱体等多种形态,非常适合表达人造场景中的规则几何体。
优化的最终目标是找到能够最好地解释所有观测图像的形状(shape)与纹理(texture)组合。论文之所以选用这类基元,正是因为它们参数少、可微分、且天然具有"可分解"的语义结构。
初始化与关键约束:只减不增
一个容易被忽略但至关重要的设计是初始化策略:优化开始时,算法会用一个初始的 block 集合(即一组超二次曲面)、一个地面平面和一个背景球体来覆盖整个场景。此后,优化过程只能减少 block 的数量,绝不能增加新的 block("the optimization can only reduce the number of blocks, not add additional ones")。
这一"只减不增"的约束带来两个直接好处:
- 搜索空间可控:优化始终在一个由初始覆盖决定的候选集合内收缩,避免了在优化中途任意插入新基元导致的组合爆炸与不稳定;
- 分解趋向简洁:由于系统倾向于删除"解释力不足"的基元,最终得到的分解天然偏向最小化的基元集合,符合"定性分解"(qualitative decomposition)的目标——不需要精确到像素级,但结构上要干净、可读。
四、透明度(Opacity):让网格数量变得可优化
README 指出,DBW 与其他可微分渲染器的一个关键区别在于对透明度的处理:
Each mesh has an opacity associated with it that is optimized. When the opacity becomes lower than a threshold the mesh is discarded in the visualization. This allows to optimize the number of meshes.
也就是说:
- 每个 mesh 都关联一个可优化的 opacity 标量;
- 优化器通过梯度同时调整 mesh 的几何、纹理与 opacity;
- 当一个 mesh 的 opacity 降到某个阈值以下时,它就在可视化中被丢弃(discard),从而在"渲染结果不变差"的前提下自动削减基元数量。
这本质上是把"结构选择(该不该有这个 block)"这一离散问题,松弛成了"opacity 该多大"这一连续可微问题,从而让整套管线可以被梯度优化驱动。opacity 低于阈值即丢弃的机制,正是"只减不增"约束在渲染层面的具体执行者。
在 Rerun 中的对应语义
在 Rerun 数据模型中,透明度由Opacity组件表达。根据 docs/content/reference/types/components/opacity.md:
Degree of transparency ranging from 0.0 (fully transparent) to 1.0 (fully opaque). The final opacity value may be a result of multiplication with alpha values as specified by other color sources. Unless otherwise specified, the default value is 1.
即 opacity 取值在0.0(完全透明)到1.0(完全不透明)之间,默认值为1,且最终显示透明度可能是该值与颜色 alpha 通道相乘的结果。这与 DBW 的优化语义完全吻合:在优化初期,大量候选 mesh 带着接近1.0的 opacity 参与渲染;随着优化推进,冗余 mesh 的 opacity 被梯度压到阈值以下,从而在可视化中消失。可以推断,原示例正是通过在优化循环中不断用 Rerun SDK 记录每个 mesh 的顶点、纹理与 opacity 值,来呈现"透明 block 逐个消失"的动态过程。
五、三阶段优化策略:稳定收敛的关键
为了稳定优化、避免陷入局部极小(local minima),论文采用了一个三阶段(3-stage)优化流程,README 对此有明确描述:
| 阶段 | 优化内容 | 目的 |
|---|---|---|
| 第一阶段 | 纹理分辨率降低 8 倍(texture resolution reduced by a factor of 8) | 先用低分辨率纹理快速探索几何形状,减少参数空间规模、加速收敛 |
| 第二阶段 | 全分辨率纹理优化(full resolution texture is optimized) | 在几何结构基本定型后,恢复完整纹理细节,精细拟合观测图像 |
| 第三阶段 | 关闭基于透明度的优化,只优化不透明 mesh(transparency-based optimization is deactivated, only optimizing the opaque meshes from here) | 冻结结构选择结果,专注打磨已存活基元的几何与纹理,避免结构反复横跳 |
这一由粗到精(coarse-to-fine)的设计,与纹理超分辨率、多分辨率渲染等经典优化技巧一脉相承:低分辨率阶段负责"找结构",高分辨率阶段负责"抠细节",最后阶段负责"锁结果"。而第三阶段"关闭透明度优化"本质上是对"结构选择已完成"的显式声明——此后每个存活 mesh 都将以全不透明状态参与最终渲染,可视化结果也更干净。
六、在 Rerun 中呈现这类优化过程:核心类型与字段
虽然该示例的可视化代码位于外部研究仓库,但我们可以从 Rerun 自身的类型定义中,理解它是如何被"可视化表达"的。下面是与 DBW 场景表示一一对应的核心类型。
Mesh3D:承载 block / 地面 / 背景网格
根据 docs/content/reference/types/archetypes/mesh3d.md,Mesh3D是一个"由逐网格与逐顶点属性指定的 3D 三角形网格",其字段与 DBW 的需求高度吻合:
- 必需字段:
vertex_positions(顶点位置,Position3D); - 推荐字段:
triangle_indices(三角形索引,TriangleIndices)、vertex_normals(顶点法线,Vector3D)——对应超二次曲面离散化后的三角网格; - 纹理相关字段:
vertex_texcoords(纹理坐标,Texcoord2D)、albedo_factor(反照率系数)、albedo_texture_buffer与albedo_texture_format(纹理图像缓冲与格式)——正好对应论文中被优化的纹理; - 材质相关字段:
vertex_colors(顶点颜色)、class_ids(类别 ID)。
文档还特别指出:网格正面采用逆时针三角形绕序(与 glTF 规范一致),且默认关闭背面剔除(back face culling)。对 DBW 这类"opacity 变化的半透明 mesh 叠放"场景,透明排序(transparency ordering)与绕序约定直接决定了可视化是否出现闪烁或错误遮挡,这正是可视化走读中需要关注的细节。
Pinhole:表达"带姿态的图像"
场景输入是"一组带姿态的图像",在 Rerun 中对应Pinhole相机投影(内参)。根据 docs/content/reference/types/archetypes/pinhole.md:
- 必需字段:
image_from_camera(PinholeProjection,即相机内参矩阵); - 推荐字段:
resolution(图像分辨率); - 可选字段:
camera_xyz(相机坐标系约定)、child_frame/parent_frame(通过命名坐标帧表达相机外参)、image_plane_distance、color、line_width。
文档同时说明:若同一父子关系上还记录了Transform3D(如相机外参),它会优先于Pinhole生效——这正是"pose 图像"在 Rerun 中的标准建模方式:内参用Pinhole,外参用Transform3D。
Transform3D 与实体层级:组织场景图
从 docs/content/concepts/logging-and-ingestion/transforms.md 可以看到,Rerun 支持两种空间关系建模:实体路径层级(每个实体通过路径表达相对父实体的变换,变换沿实体树逐级传播)与命名坐标帧(类似 ROS tf2,通过Transform3D(parent_frame=…, child_frame=…)显式建立帧间关系,且约定"每个帧在任意时刻有且只有一个父帧")。对 DBW 而言,可以推断其场景结构大致为:相机实体(Pinhole+ 外参)挂在 world 下,而每个 block/地面/背景球体作为带Transform3D的子实体挂在同一场景图中——这样优化器每更新一次参数,Rerun 就能以稳定的空间坐标呈现所有基元。
Opacity:透明度驱动的基元裁剪
如第四节所述,opacity 在 Rerun 中由Opacity组件表达,取值范围0.0–1.0、默认1、可与其他颜色源 alpha 相乘。DBW 走读中"mesh 低于透明度阈值即被丢弃"的动态效果,正是通过逐帧记录各 mesh 的 opacity 值实现的。
七、如何查看与复现这份走读
该示例在本仓库中的形态是"文档 + 可视化成果",而非独立可运行的脚本:
- 查看讲解与成果:直接阅读 examples/python/differentiable_blocks_world/README.md,其中包含论文概述、overview 静态图以及多段阶段性演示视频(优化初始化、透明度裁剪、三阶段优化各阶段),并给出了完整的论文标题与作者信息;
- 了解示例在仓库中的定位:见 examples/manifest.toml 的
3d-reconstruction类别; - 自行复现:由于这是 external example,其元数据
source字段指向外部研究仓库;复现方式与仓库中其他外部示例类似——克隆源仓库后运行其原始优化代码,并在代码中接入 Rerun SDK 的日志调用(可参考 mini_nvs_solver 这类外部示例的通用做法,其 README 以pixi run app运行)。接入时,日志数据流的骨干通常包括:rr.log记录每帧的Mesh3D(含纹理)、Pinhole(相机内参)、Transform3D(外参与基元位姿),以及各 mesh 的Opacity。
八、总结
differentiable_blocks_world示例展示了一条极具启发性的技术路径:把"3D 结构分解"这一经典难题,表示成可微渲染下的参数优化,并用 Rerun 把优化过程本身变成可回放、可检查的视觉资产。其方法要点可归纳为:
- 场景表示:背景 icosphere + 地面平面 + 超二次曲面 blocks,用少量参数化基元覆盖并解释多视图观测;
- 结构约束:初始化完整覆盖场景后,优化只允许削减 block 数量,不允许新增;
- 透明度机制:每个 mesh 的 opacity 作为可优化参数,低于阈值即被丢弃,使"基元数量"间接可微优化;
- 三阶段优化:低分辨率纹理(8 倍降采样)→ 全分辨率纹理 → 关闭透明度优化,由粗到精稳定收敛。
而 Rerun 侧提供的Mesh3D、Pinhole、Transform3D、Opacity等类型,恰好完整覆盖了该优化场景的表示与可视化需求——如果你正在从事可微渲染、神经重建或结构化 3D 分解相关研究,这份走读示例既是理解论文的直观教材,也是"如何用 Rerun 观察优化过程"的现成范式。
【免费下载链接】rerunVisualize, query, and stream to train on multimodal robotics data.项目地址: https://gitcode.com/GitHub_Trending/re/rerun
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考