AI 3D建模工具: Tripo 3D | Meshy AI

一句话结论:image-blaster 不是一个"文生 3D 模型",而是把一张图拆成"静态环境 + 动态物件 + 音效"的四个模型编排——静态环境交给 World Labs 的 Marble(出 .spz 高斯泼溅),每个动态物件交给 Hunyuan 3D v3.1(出 .glb/.obj),环境与冲击音效交给 ElevenLabs(出 .mp3),中间用 nano-banana-2 做底版清理与物件抠图。它自称"一张图到完整网格化环境 < 5 分钟"——这句话没错,但它说的是时间,不是钱:世界生成固定约 $1.34,之后每多一个物件约 +$0.46,钱全花在物件数量上。真正的坑在最后一步:导出的 .spz 与 collider 网格不带 Marble 的尺度修正,直接拖进引擎会出现尺寸与地面都不对。

披露:本文编译自该项目仓库(neilsonnn/image-blaster,MIT)的 README 与 .claude/ 下的 skill 与脚本(截至 2026-10-21 的 main 分支),以及 World Labs 官方文档(docs.worldlabs.ai)、FAL 各模型页的公开价目(2026-10-21 实查)。本文没有做端到端实测:成本数字是按管线结构与公开单价推算的账单估算,不是我们的实测账单;面数与兼容性结论来自官方文档,非我们逐项复现。作者是 World Labs 团队成员,因此对 Marble 的描述带有作者视角——这不是 World Labs 的官方产品。本站与该团队无利益关系。


一、它到底做了什么

它是一套给 Claude Code 用的 skill 包(不是一个独立 App):你在本地 clone 仓库,在仓库目录里启动 claude,把两张图之外的东西——两把 API key——交给 Claude,然后放一张图进 input/,说一句 blast it and confirm each step with me。之后每一步由 Claude 调仓库里的脚本完成,并在每步停下来向你确认。

项目 情况
仓库 neilsonnn/image-blaster,MIT
时间线 建仓 2026-04-21,最后 push 2026-05-15(HN 首发同期);11,794 ★(2026-10-21 快照)
形态 Claude Code skill 包 + Node 脚本(.claude/skills/*、.claude/scripts/*)
运行前提 只跑在 Claude Code(CLI) 里;需要 World Labs 平台 key + FAL key
输出 动态物件 .glb/.obj;静态环境 .spz;音效 .mp3
落地目标 Unity / Unreal / Godot、Blender / 3ds Max / Maya、Three.js / Electron
宣称速度 一张图 → 完整网格化环境 < 5 分钟

产物三件套——注意这三样的"性质"完全不同,这是后面所有问题的根源:

产物 格式 是什么 不是什么
静态环境 .spz(高斯泼溅) 一张可漫游的泼溅场景,Marble 出的世界 不是网格,没有面、没有 UV;引擎要专门的 splat 渲染支持
动态物件 .glb / .obj 逐个物件的真网格(Hunyuan 3D 生成) 不是整场景;物件之间没有布置关系,要你自己摆
音效 .mp3 环境循环音 + 每个物件的冲击音 不是"跟着场景自动混音"的结果,得自己按距离/材质调

另外一个容易被忽略的产物是collider 网格:脚本会把 Marble 返回的 assets.mesh.collider_mesh_url 一起下载存成 -world.glb。它是给物理碰撞用的粗网格(官方文档:GLB、10–20 万三角面,"为简单物理计算优化"),不是给渲染用的高模。

image-blaster 官方演示截帧:左侧是输入的一张图,右下是跑出来的泼溅世界(两个版本构图不同,可看出哪些内容被重新生成)

二、管线:四个模型,一条链

从仓库脚本里读到的真实调用(比 README 细一档):

input/ 一张图
  │
  ├─① 底版清理 / 物件抠图     fal-ai/nano-banana-2/edit         $0.08/张
  │                           (可切 openai/gpt-image-2/edit)
  │
  ├─② 静态环境               World Labs  marble-1.1             1,500 credits
  │      └→ .spz(full_res / 500k / 100k / 150k 全部下载)
  │      └→ collider 网格 .glb(10–20 万面)
  │
  ├─③ 每个动态物件           fal-ai/hunyuan-3d/v3.1/pro/image-to-3d   $0.375/次
  │                           (可切 .../rapid $0.225、fal-ai/meshy/v6 $0.80)
  │
  └─④ 音效                   fal-ai/elevenlabs/sound-effects/v2  $0.002/秒
          环境循环 2×10s + 每物件冲击音 4×1s

对应脚本:

环节 脚本 关键点
世界生成 .claude/scripts/world/generate-world.mjs ENDPOINT = https://api.worldlabs.ai/marble/v1,MODEL = marble-1.1
图像编辑 asset-pipeline/nano-banana-edit.mjs / gpt-image-2-edit.mjs 默认 nano-banana-2,可切 GPT Image 2
物件生成 asset-pipeline/generate-single-asset.mjs 别名表里 Hunyuan v3.1 pro 与 Meshy v6 都在,--provider meshy\|hunyuan 可切
音效 sfx/fal-elevenlabs-sfx.mjs 经 FAL 转发,不是 ElevenLabs 直连;count 上限 4

2.1 为什么第一步是"再画一遍图"

image-blast-3d 的 skill 说明书要求:在生成任何物件之前,先为这个物件写一条抠图提示——"把这个物件从图里单独隔离出来,同样的颜色/材质/比例,白底、居中、紧裁切、棚拍光、无其他物体"。

所以一个物件的真实流程是 "1 次图像编辑 → 1 次 3D 生成",不是"1 次 3D 生成"。这一步在设计上很合理(3D 模型只吃单一物件,混着背景只会更糊),但它是计费翻倍的隐藏项——第三节会算。

2.2 静态与动态,是"分工"不是"分离"

Marble 出的世界已经包含了整张图的内容(泼溅是把整幅画面三维化)。image-blaster 再让 Claude 把图里会动的东西(椅子、箱子、机器人、车)一个个抠出来做成真网格,叠在这个泼溅世界上。

这个思路很实用(泼溅便宜、网格贵),代价是:泼溅与网格之间的边界会露馅——泼溅是"看得见摸不着"的,网格是实的,两者在接触面上的遮挡、阴影、色彩响应不会自动一致。这一条所有介绍文都没提,而它是实际拼装时第一个会崩的地方。

2.3 "每步确认"是默认姿态

quickstart 的最后一句话是 blast it and confirm each step with me——不是可选项,是设计的一部分。每一步都是付费 API 调用,确认一次就是省一次钱;而 Claude 在"这张图里哪些算动态物件"上的判断,本来就需要人来拍板(判断错了,钱花了、东西不是你要的)。


三、四个参数,决定产物质量与成本

物件生成走 Hunyuan 的参数(README 原文):

参数 取值 默认 影响
--face-count 40,000–1,500,000 50,000(注意:Hunyuan API 自身默认是 500,000) 面数预算。50k 适合中远景道具;近景主角会糊
--enable-pbr true / false true 开则生成 PBR 材质;关掉更快更省,但材质要自己做
--generate-type Normal / LowPoly / Geometry Normal Normal 带贴图;LowPoly 走减面;Geometry 只有白模
--polygon-type triangle / quadrilateral triangle 仅 LowPoly 生效;四边形便于后续在 DCC 里编辑

两个容易踩的点:

  1. 50,000 是这套 skill 自己的默认,不是 API 默认。习惯 Hunyuan API 的人会以为是 500k,实际这里砍到了 1/10。好处是快、省算力;代价是近景主角一放大就露,得手动画 --face-count 重跑(重跑 = 再付一次 $0.375)。
  2. Geometry 不是"低模",是"白模":不要贴图、只要形体时用它,配合之后在 Blender 里自己展 UV——但那样就比 Normal 多一道工序。

按场景选(经验口径,非实测):

场景 建议
关卡远景 / 背景道具 默认 50k、Normal、triangle 就够
玩家会走近的物件 --face-count 150000–300000,Normal
要进 DCC 继续建模 --generate-type LowPoly --polygon-type quadrilateral
只要形体做遮挡/白模 --generate-type Geometry --enable-pbr false
快速试构图 --provider hunyuan + rapid 端点($0.225,比 pro 省 40%)

四、成本:世界是固定的,钱在物件上

先给价目(全部 2026-10-21 从官方页面实查):

项 单价 来源
World Labs 额度 $1.00 = 1,250 credits;最低起购 6,250 credits($5) docs.worldlabs.ai/api/pricing.md
世界生成 marble-1.1 1,500 credits = $1.20 同上(Usage event costs 表)
普通照片 → 先生成全景 +80 credits = $0.064 同上(Pano generation, image non-pano)
HQ 网格导出 3,500 credits = $2.80 同上(本项目没有走这条,见下)
图像编辑 nano-banana-2/edit $0.08 / 张(2K/4K ×1.5) FAL 模型页
物件 3D hunyuan-3d/v3.1/pro $0.375 / 次 FAL 模型页
物件 3D .../rapid $0.225 / 次 FAL 模型页
物件 3D meshy/v6 $0.80 / 次 FAL 模型页
音效 elevenlabs/sound-effects/v2 $0.002 / 秒 FAL 模型页

由此得到这次要的结构:

每次跑的固定成本 = 世界 1,264(1,500 + 80 credits) + 底版编辑 0.08      ≈ $1.34
每个动态物件     = 抠图编辑 0.08 + 3D 0.375 + 冲击音 4s × 0.002 = 0.008  ≈ $0.46
场景 算式 合计
1 个物件(最小可玩) 1.34 + 0.46 ≈ $1.81
5 个物件(一个房间) 1.34 + 5 × 0.46 ≈ $3.66
20 个物件(街景 / 关卡) 1.34 + 20 × 0.46 ≈ $10.60
同上,切 rapid 1.34 + 20 × (0.08 + 0.225 + 0.008) ≈ $7.62
同上,切 meshy v6 1.34 + 20 × (0.08 + 0.80 + 0.008) ≈ $19.10

三个反直觉的地方:

  1. "5 分钟"最贵的一步不是那个"世界"。Marble 出整个世界只要 $1.26,而 5 个小物件就要 $2.3。一个场景值不值,取决于物件数,不取决于画幅。
  2. 官方那个 $2.80 的 HQ 网格导出,这套流程没买。脚本只取 collider_mesh_url(10–20 万面的粗碰撞网格)。所以:如果你要"能看的静态网格",得自己回 Marble 单独导 HQ——那一步是按次 $2.80 起,且最长要等 1 小时、限每小时 4 次。这一条是本项目最容易被忽略的隐性成本。
  3. 失败即付费。面数不满意重跑、抠图不满意重抠、某个物件切错了重切——每一次都是完整的一次计费。所以 skill 才强制"每步确认"。
口径:以上是按管线结构与公开单价推算的账单估算,2026-10-21 价目,不是我们的实跑账单;未计失败重试、未计 Marble 订阅计划差异(免费计划可生成但不可导出,导出需 Standard 起;HQ 网格与商用权在 Pro)。

五、产物能不能用:先修尺度,再谈引擎

这一节是全文最实用的部分,也是最容易被跳过的一步。

5.1 自带查看器是对的,导出的文件不是

World Labs 官方文档里有一条专门给第三方引擎的说明(api/rendering-spz):

Marble 的 SPZ 文件是在"生成资产坐标系"里导出的。在 Marble 之外渲染时,必须用 assets.splats.semantics_metadata 把高斯中心与高斯尺寸换算成米制、地面贴齐的坐标。

这条元数据里有两个数,外加一个可选的朝向位:

字段 作用
metric_scale_factor 把生成资产的原始单位换算成米
ground_plane_offset 把米制地平面放到 y = 0
flip_y(可选) 翻转 Y 轴,处理坐标系差异

官方给的换算就这么几行:

def to_metric_gaussian(center, linear_scale, semantics):
    scale = semantics["metric_scale_factor"]
    metric_center = center * scale
    metric_center[..., 1] -= semantics["ground_plane_offset"]
    metric_linear_scale = linear_scale * scale

关键点:这个修正是渲染时做的,.spz 文件本身不带。

那 image-blaster 有没有处理它?把仓库拉下来 grep 一遍(2026-10-21,main 分支):

位置 读 semantics_metadata 吗
app/src/components/WorldViewer.tsx(自带的 React 查看器) 读。metric_scale_factor / ground_plane_offset / flip_y 全用上,缺省 1 / 0
.claude/scripts/**(CLI 资产管线,也就是真正交文件给你的那条) 不读。只下载 spz_urls 与 collider_mesh_url

于是问题就清楚了:在自带查看器里比例是对的,因为它替你补了修正;而落进 worlds/<name>/output/ 的 .spz 和 collider .glb 里没有这个修正。 你把它们拖进 Unity / Unreal / Blender / three.js,拿到的是一套"看起来像"、但单位不是米、地面不在 y=0 的场景。

5.2 错误长什么样,怎么修

症状很好认:

  • 不是米制:一扇门可能是 30 多个单位高,按 1 单位 = 1 米摆摄像机,你会在桌面高度看到地板。
  • 地面不在 0:所有物件要么浮空,要么半个身子陷进泼溅地面。
  • 物件与泼溅错位:两者都出自同一个世界坐标系,一个修了一个没修,接触面就必然错开——这也是后面"边界露馅"的主要成因之一。

修法三步(顺序不能反):

  1. 从世界响应里取 assets.splats.semantics_metadata。仓库脚本把 world 响应存成了 JSON(worlds/<name>/ 下),也可以直接用同一个 world_id 重新 GET 一次。
  2. 按 metric_scale_factor 缩放高斯中心与尺寸,再减去 ground_plane_offset 把地面压到 y=0。
  3. collider 网格用同一个 metric_scale_factor 缩放(这一步是推断:官方文档只写了 splat 的修正,没有提网格;但两者是同一个生成坐标系,不缩放就必然对不上)。
// three.js:加载完再统一修正,SPZLoader 只负责读文件,不做尺度换算
const world = await new SPZLoader().loadAsync(url);
const m = semantics.metric_scale_factor;
world.scale.setScalar(m);
world.position.y -= semantics.ground_plane_offset;

5.3 引擎支持面:这是"能不能用"的硬约束

先分清两样东西,它们的规模与兼容性完全不同:

产物 规模(官方规格) 谁直接吃
泼溅 SPZ(full_res) 约 200 万 个 splat three.js(addons 里有 SPZLoader);Unity / Unreal / Blender / Houdini 都要装社区 splat 插件,官方各有一份导出指南
泼溅低模 SPZ 约 50 万 / 10 万 / 15 万(仓库会把 500k/100k/150k 全下载) 同上;低模更适合进引擎(帧率)
泼溅 PLY 约 200 万 / 50 万 兼容面最广的老格式,但文件大得多——SPZ 官方说明称其比对应 PLY 小约 10 倍
碰撞网格 GLB 10–20 万三角面 任意引擎(就是普通 GLB),但它是"粗碰撞体",别当渲染网格用
HQ 网格 GLB(需 Pro) 约 60 万面带贴图 / 约 100 万面带顶点色 任意引擎;本项目流程没有生成它,要自己回 Marble 导

两个容易漏的技术细节:

  • 坐标系:SPZ 默认是 RUB(OpenGL 习惯的 Y-up 右手系),与 Unreal 的 Z-up 不一致——所以元数据里才有 flip_y 这种可选位。
  • HQ 网格不是你想要就有:官方写明最长要 1 小时、每小时限 4 次、只能对自己拥有的世界生成、且属于 Pro 计划;Free 计划能生成世界但不能导出(导出需 Standard 起)。
Marble 官方示例导出:进门的一步其实是一张 2560×1280 的等距圆柱全景(rustic kitchen 场景)

上图这张全景值得单独说一句:当你的输入不是全景图时,Marble 会先由这张图生成一张全景,再从全景生成世界——这就是价目表里那笔 +80 credits 的来源,也是"一张图"和"一个世界"之间的中间产物。

5.4 十分钟验收清单(可直接抄)

拿到产物后按顺序过一遍,任何一条不过,先别进引擎:

# 检查项 怎么查 不过怎么办
1 单位是米 找一个已知高度的参照(门 2 m、桌面 0.75 m),量一下 乘 metric_scale_factor
2 地面在 y = 0 看泼溅地面是否贴零平面 减 ground_plane_offset
3 朝向对不对 上下颠倒→查 flip_y;整体转向→查世界朝向 按需翻转/旋转
4 泼溅与网格同尺度 同一把椅子:泼溅里的和 .glb 里的叠一下 两边统一用同一个系数
5 面数够不够近景 放大到玩家视距看轮廓 重跑并调 --face-count(再付一次 $0.375)
6 碰撞体是 collider 不是渲染网格 看文件是 10–20 万面那份还是你替换的高模 渲染用高模,碰撞单独保留
7 文件体积 .spz 用低模档、.glb 看是否超预算 参考本站《AI 3D 资产的交付重量:62.89 MB 与 5.63 MB,差在哪》
8 许可能商用吗 代码是 MIT,但资产是各家 API 生成的 Marble 的商用权在 Pro 计划;各家条款单独核

六、四个要先知道的坑

尺度修好只是第一步。下面四个是拼装时真正会卡住人的地方,按"出现的早晚"排序。

6.1 静态 / 动态切分错了 → 重影

泼溅世界已经把整张图都三维化了,包括那些椅子、箱子、车。当你再让模型给"椅子"生成一个真网格叠上去,两把椅子就会同时存在:一把是泼溅里模糊的,一把是网格的。位置稍微差一点,就是重影。

而且这个循环很贵:物件清单是 Claude 看图像之后提的,它多算一个你不需要的物件,就是多付 $0.46;少算一个,那个东西就永远只是一团泼溅。

救法:在跑 3D 之前先拿到物件清单人过一遍(这正是 skill 默认 confirm each step with me 的意义);被网格替换掉的那块泼溅,接受它被网格遮住,或用简单遮罩挡一下。

6.2 泼溅与网格的边界会露馅

泼溅是"看得见摸不着"的:没有几何、不参与光照、不投影。网格是实体的。两者相交的地方,接触阴影、遮挡关系、色彩响应都不会自动一致。在静帧里看不出来,一进引擎转两圈就明显。

救法(推断,无实测):给网格物件底部加一张接触阴影贴片(AO blob),或让靠地的接触带直接用网格盖住泼溅;另外避开贴地仰拍的角度。这是所有"泼溅环境 + 生成物件"方案共同的代价,不是 image-blaster 独有的缺陷。

6.3 默认 50k 面,近景会糊

如第三节所说,50,000 面是这套 skill 自己的默认,Hunyuan API 的默认是 500,000。背景道具完全够用,但玩家会走到跟前的东西一眼能看出是生成的。重跑不便宜(每次 $0.375),所以先估好哪些物件会被走近,再一次性把 --face-count 调对。

6.4 音效只是"素材",不是"音频系统"

看它的默认参数(SKILL.md 原文):环境音 --loop --count 2 --duration-seconds 10,每个物件 --count 4 --duration-seconds 1。也就是说:

  • 环境音是 2 条 10 秒的循环,而且脚本对循环输出保留原始音频(不剪静音,为了接缝),接缝好不好要你自己听;
  • 物件音是 4 条 1 秒的冲击声,只有"撞一下",没有持续声、没有滚动声、没有材质变化;
  • 非循环输出会被 ffprobe/ffmpeg 剪掉首尾静音并做响度归一化——这是好事,但也意味着你拿到的已经不是模型原始输出的动态范围。

救法:把这 4 条当占位素材,上线前自己配;或者只用环境音,物件音自己录。

户外长街这类大尺度场景,尺度没修正时错得最明显(Marble 官方示例导出)

七、什么时候别用它

这套流程解决的问题很窄:快速拿到一个"能进去看"的场景原型。下面这些需求它不合适:

你的需求 为什么不合适 该用什么
只要一个模型,不要场景 那 $1.34 的世界钱白花 直接调 FAL 单模型(Hunyuan v3.1 pro / Meshy v6),别跑 image-blaster
尺寸要准(工程件、配件、打印) 生成不是尺寸驱动,还多一道尺度修正 参数化 CAD 路线,参见《CAD STEP ↔ Mesh 拓扑验收》
要可编辑拓扑 / 干净 UV Hunyuan 出的是"扫描式"网格,拓扑不可控 先出形体再重建,参见《STL 到可编辑 CAD》
离线 / 内网 / 不能上云 整条链路都靠两家云 API 本地文生 3D,参见《浏览器里的文生 3D:TRELLIS.2》
团队不用 Claude Code 它是一套 skill 包,不是双击即用的软件 拆开脚本单独调,或换产品化工具
商业交付,版权链要干净 代码 MIT,但资产来自各家 API;Marble 商用权在 Pro 逐个许可核实,参见《AI 生成 3D 资产的五项交接检查》

反过来说,它真正好用的场景只有一个:你手上有一张图(概念图、剧照、实拍房间、场景设计稿),想在五分钟内拿到一个能进去走两圈的原型——对齐空间感、定构图、给甲方看 Demo。做这个,它比你从头摆场景快太多。

八、相关阅读

如果你在评估"图片 / 文本 → 3D"这条路,下面几篇能接着看:

想解决的问题 文章
不想上云,想在本地/浏览器里跑 浏览器里的文生 3D:TRELLIS.2 跑在 WebGPU 上
另一个"skill 做 3D"的样本 Monument Skill:3D 重建 Agent
产物拿到手之后怎么验 水密不等于可打印:AI 3D 资产的验收 · 支撑与网格审计
体积与交付重量(62.89 MB vs 5.63 MB) AI 3D 资产的交付重量
物件级的交接检查(尺度/贴图/拓扑/归属) AI 生成 3D 资产的五项交接检查
要精密尺寸就别走生成路线 CAD STEP ↔ Mesh 拓扑验收

更多 AI 3D 内容在专题页:AI × 3D / 生成式 AI 完全指南


九、来源与边界

来源(均为 2026-10-21 访问):

  1. 仓库 neilsonnn/image-blaster(MIT):README.md;.claude/skills/image-blast-3d/SKILL.md;.claude/skills/image-blast-sfx/SKILL.md;.claude/scripts/world/generate-world.mjs;.claude/scripts/asset-pipeline/{nano-banana-edit,gpt-image-2-edit,hunyuan-3d,meshy-3d,generate-single-asset}.mjs;.claude/scripts/sfx/fal-elevenlabs-sfx.mjs;app/src/components/WorldViewer.tsx
  2. World Labs 官方文档:api/pricing(额度与 usage events)、marble/export/specs(spz/ply/collider/HQ 网格规格)、marble/export/gaussian-splat(导出计划限制)、api/rendering-spz(尺度修正)
  3. FAL 模型页:fal-ai/hunyuan-3d/v3.1/pro/image-to-3d($0.375)、.../rapid/image-to-3d($0.225)、fal-ai/meshy/v6/image-to-3d($0.80)、fal-ai/nano-banana-2/edit($0.08)、fal-ai/elevenlabs/sound-effects/v2($0.002/s)
  4. 格式规范:Niantic spz(约比 PLY 小 10 倍、默认 RUB 坐标系)、three.js examples/jsm/loaders/SPZLoader.js
  5. 示例图:Marble 官方示例导出(wlt-ai-cdn.art/example_exports/*_pano.png);image-blaster 官方演示动图(GitHub)

边界(请当真的边界看)

  • 本文没有做端到端实测:没跑过真实 blast,没有自己的账单;所有金额是按管线结构与官方单价推算的估算。
  • 面数、引擎兼容性、许可证限制来自官方文档与仓库代码,未逐项复现(尤其各引擎的 splat 插件支持度变化很快,以你用的版本为准)。
  • 标注为"推断"的两处(collider 网格需同比例缩放、边界露馅的救法)没有官方文档背书,属于经验外推。
  • 项目归属:作者是 World Labs 团队成员,但不是 World Labs 官方产品;本文对 Marble 的描述相应带有作者视角。
  • 价格会变:尤其是 FAL 的模型单价与 World Labs 的 credits 表;商用前请以当日官网价目与你自己的账单为准。

本文由 BimAnt 编译整理,转载请注明出处。