前馈3D生成模型
概述
传统的3D重建方法(如SfM+MVS)需要多视角图像且计算耗时。前馈3D生成模型(Feedforward 3D Generation Models)实现了从单张图像直接预测3D表示的突破,显著降低了3D内容创建的门槛。
前馈模型的核心优势:
- 单图像输入:无需多视角或姿态信息
- 快速推理:秒级甚至毫秒级3D生成
- 泛化能力:在大规模数据上预训练,可泛化到新物体类别
- 端到端:无需后处理pipeline
LRM: Large Reconstruction Model
概述
LRM (Large Reconstruction Model) 是由Shanghai AI Lab等机构提出的前馈3D生成模型,能够从单张图像在约5秒内生成3D表示。
架构设计
LRM采用三阶段架构:
输入图像 → 视觉编码器 → 三平面解码器 → 神经渲染器 → 3D网格
视觉编码器
使用预训练的DINOv2或OpenCLIP作为视觉编码器:
class VisionEncoder:
def __init__(self):
self.dino = torch.hub.load('facebookresearch/dinov2', 'dinov2_vitl14')
def encode(self, image):
# 输出: (B, 1024, H', W')
features = self.dino(image)
return features三平面解码器
三平面(Triplane)是3D场景的紧凑表示,由三个正交平面组成:
每个平面特征图尺寸为 ,其中 是特征维度。
三平面生成:
class TriplaneDecoder:
def __init__(self, feature_dim=80):
self.transformer = TransformerDecoder(dim=1024)
self.triplane_head = nn.Linear(1024, 3 * 256 * 256 * feature_dim)
def decode(self, image_features):
"""
image_features: (B, 1024, H', W')
输出: (B, 3, 256, 256, feature_dim) 三平面特征
"""
# 使用交叉注意力处理图像特征
triplane_flat = self.transformer(image_features)
triplane = self.triplane_head(triplane_flat)
triplane = triplane.view(-1, 3, 256, 256, 80)
return triplane神经渲染器
使用类似NeRF的体积渲染从三平面渲染视图:
class NeuralRenderer:
def render_from_triplane(self, triplane, camera_pose):
"""从三平面渲染指定视角"""
# 沿射线采样
rays = get_rays(camera_pose)
# 体积渲染
rgb, depth = volume_render(triplane, rays)
return rgb, depth训练策略
数据集
LRM在Objaverse数据集上训练:
- 约150K个带渲染图像和3D网格的样本
- 涵盖多种物体类别和风格
损失函数
- :RGB重建损失
- :深度预测损失
- :掩码预测损失
性能对比
| 方法 | 推理时间 | 泛化性 | 几何质量 |
|---|---|---|---|
| LRM | ~5秒 | 良好 | 良好 |
| Point-E | ~30秒 | 中等 | 中等 |
| Shap-E | ~10秒 | 中等 | 中等 |
| 优化方法 | 分钟级 | 优秀 | 优秀 |
TripoSR
概述
TripoSR是由VAST AI和MIT联合开发的前馈3D重建模型,在保持高质量的同时实现了更快的推理速度。
核心创新
网格优先输出
与LRM输出NeRF不同,TripoSR直接预测网格表示:
输入图像 → 视觉编码器 → Transformer → 三平面 → Marching Cubes → 网格
网格表示
有符号距离场(SDF):
定义物体表面,通过Marching Cubes提取等值面。
神经SDF解码器:
class SDFDecoder(nn.Module):
def __init__(self, triplane_dim=80):
super().__init__()
self.decoder = nn.Sequential(
nn.Linear(triplane_dim * 3, 256),
nn.ReLU(),
nn.Linear(256, 256),
nn.ReLU(),
nn.Linear(256, 1) # 预测SDF值
)
def forward(self, triplane, points):
"""
triplane: (B, 3, H, W, D, C)
points: (B, N, 3)
"""
# 从三平面插值特征
features = sample_triplane(triplane, points)
sdf = self.decoder(features)
return sdfMarching Cubes提取
def extract_mesh(sdf_decoder, triplane, threshold=0.0, resolution=128):
"""使用Marching Cubes提取网格"""
# 创建3D网格点
points = create_grid(resolution)
# 预测SDF值
sdf_values = []
for batch in points.split(batch_size):
sdf = sdf_decoder(triplane, batch)
sdf_values.append(sdf)
sdf_values = torch.cat(sdf_values)
# Marching Cubes
vertices, faces = marching_cubes(sdf_values, threshold)
return vertices, faces训练配置
数据增强
- 随机视角渲染:训练时随机生成输入视角
- 背景扰动:改变背景颜色和纹理
- 遮挡模拟:添加随机遮挡物
课程学习
- 阶段1:简单物体(单物体、干净背景)
- 阶段2:复杂物体(多物体、杂乱背景)
- 阶段3:开放世界(真实场景图像)
One-2-3-45系列
One-2-3-45
核心思想
One-2-3-45提出了从单图像生成完整3D物体的pipeline:
- 多视角生成:使用Zero123预测多视角图像
- 多视角融合:使用NeRF融合多视角信息
- 网格提取:从NeRF提取高质量网格
Zero123
Zero123是单图像到多视角的扩散模型:
class Zero123Plus:
def __init__(self):
self.unet = load_pretrained_unet()
self.vae = load_pretrained_vae()
def predict_views(self, input_image, num_views=24):
"""
输入: 单张图像
输出: 24个视角的图像
"""
# 编码输入图像
x = self.vae.encode(input_image)
# 在条件图像上添加噪声
x_noisy = add_noise(x, t)
# 预测目标视角
output = self.unet(x_noisy, context=target_view_embedding)
return self.vae.decode(output)One-2-3-45++
改进点
- 即时生成:推理速度从分钟级降到秒级
- 直接网格预测:跳过NeRF中间表示
- 改进的几何:更好的表面细节
架构
单图像 → 视觉编码器 → 3D表示解码器 → 网格
可微网格渲染:
- 使用软渲染器评估几何质量
- 通过网格顶点反向传播梯度
class DifferentiableMeshRenderer:
def __init__(self):
self.soft_alpha = 0.5 # 软alpha值
def render(self, vertices, faces, textures, camera):
"""可微渲染"""
# 渲染参数化网格
images = soft_rasterize(vertices, faces, textures, camera)
return images
def backward(self, grad_images):
"""反向传播"""
grad_vertices, grad_textures = ...
return grad_vertices, grad_texturesCRM: Image-to-3D via Mesh
概述
CRM提出了图像→网格→纹理的端到端pipeline。
三阶段架构
阶段1:粗糙几何预测
使用大模型(如DINO、CLIP)提取图像特征,预测低分辨率SDF。
阶段2:网格细化
使用图神经网络细化网格顶点位置。
class MeshRefiner(nn.Module):
def __init__(self):
self.edge_conv = EdgeConv()
self.vertex_update = VertexUpdate()
def refine(self, vertices, faces):
"""细化网格"""
# 构建邻接图
G = build_graph(vertices, faces)
# 多轮图卷积
for _ in range(num_layers):
features = self.edge_conv(G, vertices)
vertices = self.vertex_update(vertices, features)
return vertices阶段3:纹理生成
使用纹理扩散模型为网格添加纹理:
class TextureGenerator:
def __init__(self):
self.unet = load_diffusion_unet()
self.mesh_encoder = MeshEncoder()
def generate_texture(self, mesh, image_condition):
"""生成纹理"""
mesh_features = self.mesh_encoder(mesh)
texture = self.unet(
noise=noise,
context=concat(mesh_features, image_features)
)
return textureInstant3D
概述
Instant3D提出了几何-纹理解耦的3D生成方法,实现了高质量实时生成。
几何-纹理分离
几何分支
class GeometryBranch(nn.Module):
"""预测SDF几何"""
def forward(self, image):
features = self.encoder(image)
sdf_volume = self.decoder(features)
return sdf_volume纹理分支
class TextureBranch(nn.Module):
"""预测纹理图"""
def forward(self, image, geometry):
features = self.encoder(image)
geometry_features = self.geometry_encoder(geometry)
texture_map = self.decoder(concat(features, geometry_features))
return texture_map推理流程
def instant3d_inference(image):
# 1. 几何预测(约0.5秒)
sdf = geometry_branch(image)
# 2. 网格提取
mesh = marching_cubes(sdf)
# 3. 纹理生成(约1秒)
texture = texture_branch(image, mesh)
# 4. UV映射
textured_mesh = map_texture(mesh, texture)
return textured_mesh性能对比与选型指南
定量对比
| 模型 | 推理时间 | 几何质量 | 纹理质量 | 泛化能力 |
|---|---|---|---|---|
| LRM | ~5秒 | 良好 | 良好 | 良好 |
| TripoSR | ~0.5秒 | 优秀 | 良好 | 良好 |
| One-2-3-45++ | ~10秒 | 优秀 | 优秀 | 中等 |
| CRM | ~30秒 | 优秀 | 优秀 | 良好 |
| Instant3D | ~1.5秒 | 良好 | 优秀 | 中等 |
选型建议
| 场景 | 推荐模型 | 原因 |
|---|---|---|
| 实时应用 | TripoSR | 最快推理速度 |
| 高质量资产 | One-2-3-45++ | 最佳质量 |
| 泛化性需求 | LRM | 最好泛化 |
| 纹理优先 | Instant3D | 纹理质量高 |
技术挑战与局限
几何歧义
单图像3D重建本质上是歧义问题:
- 尺度歧义:无法确定绝对尺度
- 深度歧义:前后关系不确定
- 遮挡歧义:被遮挡部分无法观察
泛化性限制
- 训练数据分布影响泛化能力
- 罕见物体类别表现较差
- 真实场景 vs 合成物体差异
计算资源
- 高分辨率输出需要更多GPU内存
- 实时应用受限于设备算力
前沿方向
扩散模型增强
将扩散模型用于3D生成:
- 3D扩散:Point-E, Pure3D
- 改进的先验知识利用
- 更好的一致性保证
多模态条件
结合多种输入条件:
- 文本+图像
- 草图+图像
- 深度+图像
场景级重建
从物体级扩展到场景级:
- RoomDreamer
- MVDiffusion