MeshFlow
MeshFlow:高效艺术风格 3D 网格生成
论文:MeshFlow: Efficient Artistic Mesh Generation via MeshVAE and Flow-based Diffusion Transformer
代码:facebookresearch/meshflow
arXiv:2606.04621
1. 一句话理解
MeshFlow 把 3D 网格生成改成下面这件事:
传统方法逐个生成顶点和三角面;MeshFlow 先把网格压缩成连续 latent,再并行生成整个网格。
2. 为什么网格生成困难?
一个三角网格包含两类信息:
| 信息 | 例子 | 特点 |
|---|---|---|
| 几何 | 顶点坐标 \((x,y,z)\) | 连续 |
| 拓扑 | 哪些顶点相连、哪些点组成三角面 | 离散 |
传统自回归方法通常这样生成:
主要问题:
- 网格越大,串行步骤越多;
- 坐标常被离散成有限等级,产生量化误差;
- 序列可能提前结束,生成不完整网格。
3. 核心设计:把离散拓扑变成连续向量
MeshFlow 最终希望用三组信息表示每个顶点:
其中:
- \(v_i\):顶点坐标;
- \(n_i\):顶点法线;
- \(e_i\):边连接特征,也叫 edge embedding。
这里的 \((v_i,n_i,e_i)\) 是模型的输出表示 / 解码后表示。它不等于编码器的原始输入。
3.1 用 embedding 判断是否有边
对两个顶点 \(i,j\),从 \(e_i\) 和 \(e_j\) 计算边连接分数。开源实现使用时空距离形式的分数:
开源代码在 \(s_{ij}>\tau\) 时判断两点相连。这个分数不是普通欧氏距离,不能简单理解成“越近越相连”。
因此,离散邻接矩阵被连续向量计算出的连接分数替代。论文正文的示意判定式写作 \(d\leq\tau\),但损失式和开源代码使用的是相反方向;这里按照实际实现说明。
3.2 用三条边恢复三角面
如果三个顶点两两相连,就恢复一个三角面:
3.3 用法线恢复面朝向
三条边只能确定三角形的三个点,不能确定顺时针还是逆时针。
MeshFlow 使用顶点法线的平均值作为面方向:
再与坐标计算出的面法线比较;方向相反时交换两个顶点的顺序。
4. MeshVAE:把网格压缩成 latent
4.1 编码器输入
要特别区分三个层次:
| 层次 | 每个顶点包含的内容 |
|---|---|
| 编码器输入 | 位置、法线、由真实邻接关系找到的邻居坐标 |
| latent | 压缩后的连续隐藏向量 |
| 解码器输出 | 重建位置、法线、edge embedding、有效顶点 mask |
按照论文的设计,编码器输入由以下三部分组成:
其中:
- \(\operatorname{PE}\):Fourier positional encoding;
- \(\mathcal{N}_i\):顶点 \(i\) 的邻居;
- 邻居坐标提供局部几何和拓扑信息。
这里的关键点是:edge embedding 不在论文编码器输入公式中,而是在解码器输出中出现。 编码器读取真实网格的离散邻接关系,先找到邻居坐标;解码器无法直接输出离散邻接矩阵,因此改为预测连续的 edge embedding,再由它恢复拓扑。
还要区分论文公式和开源代码的默认配置:
| 来源 | 实际输入 |
|---|---|
| 论文方法 | \(\operatorname{PE}(v_i)\)、\(\operatorname{PE}(n_i)\)、邻居顶点坐标 |
| 开源代码 | embedder(padded_verts) 加上 point_feats_type 中配置的特征 |
代码默认的 point_feats_type 是 ["verts_normal"],所以默认一定有:
邻居坐标只有在配置中加入 neighbor_points 时才会进入编码器。法线只有在配置写成 embed@verts_normal 时才会经过同一个 Fourier embedder;写成 verts_normal 时使用原始三维法线。实际运行应以 checkpoint 的 config.yaml 为准。
4.2 压缩过程
TokenMerge 类似 PixelShuffle,把多个顶点 token 的信息合并到更少的 token 中。
4.3 解码过程
解码器输出:
5. MeshVAE 的训练目标
总损失为:
| 损失 | 作用 |
|---|---|
| \(\mathcal{L}_{mask}\) | 判断当前位置是不是有效顶点 |
| \(\mathcal{L}_{v}\) | 让预测坐标接近真实坐标 |
| \(\mathcal{L}_{n}\) | 让预测法线接近真实法线 |
| \(\mathcal{L}_{adj}\) | 区分相连和不相连的顶点 |
| \(\mathcal{L}_{kl}\) | 让 latent 接近标准高斯分布 |
拓扑对比损失的直观目标:
这样,解码器不需要直接预测离散邻接矩阵,也能恢复网格拓扑。
6. Flow DiT:从噪声生成整个网格
6.1 训练阶段
设真实网格 latent 为 \(z_0\),随机噪声为 \(\epsilon\):
构造中间状态:
于是:
- \(t=0\):真实 latent;
- \(t=1\):纯噪声。
DiT 学习预测这条直线的速度:
训练目标:
其中 \(c\) 是点云或图像条件。
6.2 推理阶段
推理时从噪声出发,沿着 DiT 预测的方向逐步回到真实网格 latent。
6.3 为什么速度快?
| 自回归生成 | MeshFlow |
|---|---|
| 一个 token 接一个 token 生成 | 所有 latent token 同时处理 |
| 生成长度随网格变大 | 去噪步数基本固定 |
| 容易提前终止 | 统一输出完整 token 集合 |
| 通常需要离散坐标 | 直接生成连续坐标 |
7. 如何加入输入形状?
点云条件
点云先被粗略体素化,再通过 3D RoPE 注入 DiT:
模型还把目标顶点数作为条件,控制输出网格的分辨率。
参考图像条件
开源实现支持可选的参考图像:
点云主要控制三维形状,图像主要提供外观和风格参考。
8. 网格提取算法
MeshVAE 解码后还不是最终三角网格,论文继续执行:
修补步骤主要处理扩散预测不准确造成的小孔洞:
边界边 → 找到闭合多边形环 → 对小环重新三角化
9. 训练和推理的完整流程
训练
推理
10. 实验结果
在 Toys4K 测试集上,数值越低越好:
| 方法 | Chamfer Distance | Hausdorff Distance |
|---|---|---|
| FastMesh-V4K | 4.05 | 10.22 |
| MeshFlow | 2.33 | 4.23 |
单个物体的推理时间约为:
| 方法 | 时间 |
|---|---|
| BPT | 约 8 分钟 |
| TreeMeshGPT | 约 4 分钟 |
| FastMesh-V1K | 约 21 秒 |
| MeshFlow | 约 1.2 秒 |
MeshVAE 的特点:
- 连续表示,避免坐标量化;
- latent token 数量约为原始顶点的四分之一;
- 四倍下采样时,边结构 F1 仍约为 \(0.89\)。
11. 优点和局限
优点
- 生成速度快;
- 顶点坐标保持连续;
- 网格表示紧凑;
- 支持点云和参考图像条件;
- 不需要逐个生成三角面。
局限
- edge embedding 的分数阈值判断可能产生错误连接;
- 扩散预测不准时可能出现孔洞;
- Chamfer Distance 不能完整评价拓扑质量;
- 完整训练需要大规模数据和 GPU 资源。
12. 最终总结
MeshFlow 的核心可以压缩成三个动作:
对应的技术含义是:
- 用顶点 embedding 计算连接分数来表示边;
- 用 MeshVAE 把网格压缩到紧凑 latent;
- 用 Flow Matching 从噪声并行生成整个 latent;
- 解码后再通过几何规则恢复三角面。
最关键的思想是:
先把离散网格变成连续、紧凑的表示,再使用扩散模型生成。
本文来自博客园,作者:S-X-Q,转载请注明原文链接:https://www.cnblogs.com/sxq-blog/p/23154069

浙公网安备 33010602011771号