PhysForge:从一张图片生成可交互的 3D 物体
PhysForge:从一张图片生成可交互的 3D 物体
一句话:先由 VLM 写出“物理蓝图”,再由生成模型把部件形状和运动关节一起生成出来。
普通 3D 生成器主要解决“物体长什么样”。PhysForge 还要解决“物体怎样被操作”。例如输入一张柜子图片,输出不只是一个柜子 mesh,还应包含:柜体、柜门、把手;柜门连接到柜体;把手固定在柜门;柜门绕铰链旋转。
1. 先记住四层数据
理解 PhysForge 最容易混淆的地方,是把不同层次的信息混在一起。它实际上有四层:
整体物体
└─ 部件结构:柜体、柜门、把手
└─ 粗体素:每个部件大概占据哪些空间位置
├─ 几何特征:部件长什么样
└─ KineVoxel:这个部件怎样运动
但最后一层有一个重要区别:
几何特征通常有多个,对应部件中的多个几何 voxel;KineVoxel 通常是部件级的,一个可动部件对应一份关节表示。
它不是“每一个几何 voxel 都有一套铰链参数”。
2. 全流程
VLM 和第二阶段的分工是:
| VLM 规划阶段 | 第二阶段生成阶段 |
|---|---|
| 有哪些部件 | 部件具体长什么样 |
| 每个部件的粗略位置 | 铰链精确在哪里 |
| 谁是谁的父部件 | 关节轴朝哪个方向 |
fixed、revolute、prismatic 等类型 |
运动范围是多少 |
| 材料、质量、功能、状态等语义 | 最终 mesh、纹理和连续关节参数 |
3. 第一阶段:VLM 生成物理蓝图
3.1 输入
规划器使用 Qwen2.5-VL,接收三类信息:
- 图片:提供外观、类别和可见结构;
- 可选 2D mask:帮助控制部件划分的粒度;
- 粗 3D 体素:提供三维空间线索,例如前后关系、厚度和位置。
图片和 mask 经过图像编码器。粗体素先经过 PartField 提取部件相关特征,再经过位置感知的 3D 卷积。论文提到输出特征宽度为 512;这表示特征向量的维度,不是体素数量。
3.2 输出
VLM 输出一条完整的、结构化的蓝图序列。对第 \(i\) 个部件,可以抽象成:
- \(b_i\):三维轴对齐包围盒;
- \(\pi_i\):父部件;
- \(\tau_i\):关节类型;
- \(\Phi_i\):材料、质量、功能、状态和可供动作等属性。
教学示例:
整体:储物柜,场景 = 卧室
柜体:
bbox = 主体区域
parent = base
joint = fixed
function = 容纳物品
柜门:
bbox = 正面薄板区域
parent = 柜体
joint = revolute
function = 开闭储物空间
state = [关闭, 打开]
把手:
bbox = 门外侧小区域
parent = 柜门
joint = fixed
affordance = [抓取, 拉动]
因此,VLM 直接给出的是:
柜门连接到柜体,类型是 revolute
把手连接到柜门,类型是 fixed
它不直接给出铰链的精确连续数值:
Joint origin = (x, y, z)
Joint axis = (ax, ay, az)
Joint limits = (lower, upper)
这些数值由第二阶段生成。
3.3 是多轮对话吗?
论文描述的是一次规划任务中,VLM 自回归地生成完整蓝图序列:
整体类别
→ Part-1 的包围盒和属性
→ Part-2 的包围盒和属性
→ Part-2 的父部件和关节类型
→ ...
→ 结束标记
所以可以理解为:一次输入、一次完整规划输出;内部一个 token 接一个 token 地生成。 论文没有描述把整体信息、部件信息和关系信息拆成三次独立调用,也没有公开完整的 prompt 和字段顺序。
3.4 包围盒如何表达?
一个三维包围盒需要 6 个坐标:
PhysForge 增加了 64 个离散坐标 token:<box0> 到 <box63>,以及 <boxs>、<boxe> 两个边界 token。因此一个包围盒可以用 6 个坐标 token 紧凑表示。
教学示例:如果坐标已经归一化到 \([0,1]\),可以用
把坐标映射到 64 档。\(u\approx0.5\) 时,大约对应 <box32>。这是帮助理解的简化示例,论文没有公开所有坐标归一化细节。
3.5 为什么物理属性能帮助分部件?
只看外观时,柜门和把手可能颜色相近。若模型还要同时回答:
把手可以抓取
柜门负责开闭
把手固定在柜门上
这些功能和关系会帮助它把两个部件分开。因此,物理属性不仅是蓝图的输出,也为部件划分提供了额外语义约束。
4. 第二阶段的基础:OmniPart 如何生成部件 mesh?
PhysForge 的几何生成部分建立在 OmniPart 的第二阶段上。先理解 OmniPart 的核心流程。
4.1 整体粗体素先变成部件候选体素
TRELLIS 第一阶段先根据图片生成整个物体的稀疏 active voxel。它们描述物体整体大致占据的空间,不是最终 mesh。
VLM 给出每个部件的 bbox 后,系统从整体 active voxel 中取出位于 bbox 内的候选 voxel:
整体 active voxel
↓ 用柜门 bbox 裁剪
柜门候选 voxel
↓ 预测有效性,丢掉误包含的 voxel
柜门有效 voxel
形式上可以写成:
这里的 \(s_i(v)\) 是候选 voxel 属于部件 \(i\) 的有效性分数。
教学示例:柜门 bbox 圈进 10 个 voxel,其中 2 个属于柜体边缘。模型可以给这 2 个 voxel 较低的有效性分数,最后过滤掉它们。这个机制可以去掉误包含的 voxel,但不能补回 bbox 外漏掉的 voxel。
这不是“每个部件从零开始独立搜索 active voxel”,而是“整体 active voxel → bbox 取候选 → 有效性过滤”。
4.2 每个几何 voxel 有什么?
在 TRELLIS 的结构化 latent 中,一个 active voxel 通常由两部分组成:
空间位置 p_i + 局部特征 f_i
局部特征包含该位置附近的几何和外观信息。一个部件通常包含多个这样的几何 voxel,因此它对应的是一串几何 latent,而不是一个单独的几何向量。
OmniPart 同时保留:
整体物体 latent
+ 柜体 latent
+ 柜门 latent
+ 把手 latent
不同部件加入不同的 part position embedding,告诉 Transformer 哪些 token 属于同一个部件。整体 latent 提供全局上下文,防止部件互相漂浮或比例不一致。
4.3 OmniPart 如何得到 mesh?
生成过程可以概括为:
它不是“先生成完整 mesh,再切成部件”,而是先把不同部件放进不同的 latent 区域,再同时生成这些部件。共享 Transformer 让局部部件和整体形状保持一致。
5. PhysForge 的新增:部件级 KineVoxel
OmniPart 解决的是“部件长什么样”。PhysForge 还要解决“部件怎样运动”。
5.1 一个可动部件的关节参数
对第 \(i\) 个可动部件,关节参数写成:
其中:
- \(O_i\in\mathbb R^3\):关节原点,例如铰链位置;
- \(A_i\in\mathbb R^3\):关节轴方向;
- \(L_i\in\mathbb R^2\):运动下限和上限。
例如柜门:
joint type = revolute
O = 铰链位置
A = 竖直方向
L = [0°, 90°]
5.2 KineVoxel 不是普通的空间 voxel
论文把 \(P_i\) 编码成一个特殊的 KineVoxel:
这里的 \(z_{k,i}\) 是一个部件级运动学 latent/token。它的名字里虽然有 voxel,但它不表示空间中新增了一块实体体素。
更直观地说:
柜门的多个几何 latent:描述柜门长什么样
柜门的一个 KineVoxel:描述柜门怎样运动
如果一个物体有多个可动部件,通常会有多个部件级运动学表示;固定部件不需要独立的运动参数。
5.3 关节类型如何进入第二阶段?
VLM 预测的 revolute、prismatic 等类型会变成类型 embedding:
这很重要,因为同样的“轴方向”在不同关节类型下含义不同:
revolute:绕轴旋转;prismatic:沿轴平移;fixed:不产生相对运动。
5.4 几何特征和 KineVoxel 如何交互?
在几何 latent 下采样后,系统将几何 token 序列和 KineVoxel 序列拼接,再送入共享的中间 Transformer:
因此,二者的关系是:
多个几何 latent + 一个部件级 KineVoxel
↓
共享 Transformer 交换信息
↓
几何解码器 + 运动学解码器
这让柜门的几何形状可以帮助定位铰链,而 revolute 类型又能约束运动参数应按旋转关节解释。
训练时,运动学编码器可以接收真实关节参数作为监督。推理时,没有真实铰链位置;运动学 latent 和几何 latent 都从噪声状态开始,随生成过程逐步更新。
6. 第二阶段如何训练和推理?
6.1 训练:学习从噪声走向目标
第二阶段使用 Conditional Flow Matching。直观地说,训练时模型看到一个处于中间状态的几何和运动学 latent,学习它们应该朝哪个方向更新。
教学示例:一维情况下,噪声为 \(-1\),目标为 \(3\),可以用
连接二者。模型看到当前状态、时间和蓝图条件后,预测更新方向。实际任务中的 \(X\) 同时包含几何 latent 和运动学 latent。
几何与运动学分别计算速度误差:
运动学项权重更大,表示训练时特别重视关节参数的精度。
6.2 推理:从随机 latent 生成资产
输入:图片,可选 2D mask
粗体素 ← TRELLIS 第一阶段
蓝图 ← VLM(图像, 粗体素, mask)
根据 bbox 得到各部件候选粗体素
初始化几何 latent 和部件级运动学 latent
重复多个时间步:
用蓝图、几何 latent 和 KineVoxel 预测更新方向
同时更新几何与运动学 latent
部件 mesh ← 几何解码器(最终几何 latent)
关节参数 ← 运动学解码器(最终运动学 latent)
按蓝图中的父子关系组装资产
最终输出包括:
部件 mesh 与纹理
部件父子关系
材料、质量、功能等属性
关节类型
关节原点、轴方向、运动范围
7. 完整例子:柜门如何打开?
下面是教学示例,数值不代表论文实验结果。假设 VLM 输出:
柜体 = base
柜门 = 柜体的 revolute 子部件
把手 = 柜门的 fixed 子部件
接着,从整体粗体素中按柜门 bbox 取出柜门候选 voxel。柜门的多个几何 latent 描述门板、边缘和厚度;另外生成一个部件级 KineVoxel,表示:
这表示柜门绕竖直轴从关闭状态旋转到 90 度。门上任意一点 \(x\) 的位置可以写成:
把手是柜门的固定子部件,所以它继承柜门的运动:
如果输入的是抽屉,VLM 可能预测 prismatic。此时第二阶段生成的轴表示滑动方向,运动可以写成:
因此,关节类型是两阶段之间的重要接口:VLM 决定“旋转还是平移”,KineVoxel 生成“具体轴、位置和范围”。
8. 数据和边界
PhysForge 使用 PhysDB,为约 15 万个物体提供四层标注:
- 整体:类别、尺度、使用场景;
- 静态:部件、材料、质量;
- 功能:用途和状态机;
- 交互:可供动作、父子关系和关节类型。
PhysDB 主要帮助学习物理属性和高层结构。精确关节原点、轴方向和运动范围还使用 PartNet-Mobility 与 Infinite-Mobility 的运动学数据进行训练。
“physics-grounded”表示生成结果具有物理语义、部件层次和运动学结构,并不等于每个结果都已经通过真实仿真验证。论文没有把完整的碰撞、摩擦、惯性或控制器调参都交给 VLM 预测;这些仍可能需要部署阶段处理。
单张图片也无法消除遮挡、背面和内部结构的歧义。因此它更像是根据视觉和常识生成一个合理的可交互资产,而不是保证得到现实物体的精确数字孪生。
9. 五句话记住方法
- TRELLIS 先从图片得到整个物体的粗 active voxel。
- VLM 输出部件 bbox、属性、父子关系和关节类型。
- 每个部件从整体 active voxel 中取候选区域,再形成多个几何 latent。
- 每个可动部件额外有一个部件级 KineVoxel,表示关节原点、轴和运动范围。
- 几何 latent 与 KineVoxel 经过共享 Transformer 联合生成,最后分别解码为 mesh 和运动学参数。
本文来自博客园,作者:S-X-Q,转载请注明原文链接:https://www.cnblogs.com/sxq-blog/p/23068545

浙公网安备 33010602011771号