这篇教程走一遍完整链路:写一句描述、可选补参考图、生成候选、导出模型文件、修网格、重拓扑、在 Blender 里改造,然后拼进一个真实场景。走完之后你手上会有一个干净的 .glb 文件,既能拖进 Blender 继续编辑,也能直接丢进网页或游戏引擎。
这篇能做出什么
具体成果是一个可复用的小道具资产,比如"黄铜复古手电筒"。它会满足这些条件:
- 单一物体,不是一堆零件糊在一起
- 带材质和贴图,导出去颜色不丢
- 面数可控,能在编辑器里流畅旋转
- 有干净的 UV,后续可以换贴图
- 原点在物体中心,朝向和单位跟场景一致
Astra 的具体界面、参数项名称、支持的导出格式,以官方文档当前版本为准。下面写的是工作流本身,换任何同类 3D 生成工具都能套。
前置条件清单
- 能访问 Astra 3D 生成能力的入口(网页控制台、API 或编辑器插件均可)
- Blender,版本以官网当前稳定版为准
- Node.js 环境,用来跑
gltf-transform命令行工具(可选,但批处理时很好用) - Python 加
trimesh,用来批量做网格体检(可选) - 一张白底参考图(可选,但能明显提升可控性)
- 心理预期:单次走完整条链路大约 30 到 60 分钟
步骤 1:先把"用在哪"写清楚
提示词写得再好,如果自己不知道要做低模还是高模,生成结果一定来回返工。动笔之前先填一张规格表。
| 项目 | 示例值 |
|---|---|
| 用途 | 网页 3D 展厅里的展品道具 |
| 目标面数 | 2 万面以内 |
| 是否需要贴图 | 需要,颜色贴图即可 |
| 真实尺寸 | 长约 20 厘米 |
| 朝向 | 正面朝 +Z |
| 是否需要骨骼 | 不需要 |
这张表会直接决定后面的提示词写法、导出格式和是否要减面。跳过这一步,后面每一步都会来回改。
步骤 2:把一句话扩写成结构化提示词
一句话原始描述通常是"一个复古手电筒"。这个信息量对 3D 生成来说太少,模型只能自己猜,猜出来的东西不可控。
把它拆成五段:主体形态 + 材质 + 风格 + 结构约束 + 画面约束。
```text
主体形态:圆柱形筒身的手电筒,前端有防滑滚花,尾部带金属挂环,头部略粗
材质:磨砂黄铜,表面有细微做旧和氧化痕迹
风格:写实风格,细节适中
结构约束:单一物体,左右对称,细杆和挂环保持连通,不要碎裂成多个零件
画面约束:居中,纯白背景,无阴影,无其他物体
```
几个让结果更稳的经验:
- 主体用具体名词,别用"某种""之类的"这种模糊词
- 写清楚"单一物体",否则容易生成一摊融在一起的东西
- 细长结构(挂环、链条、细杆)容易被吞掉,要单独强调"保持连通"
- 想控制拓扑就写"以四边形为主、面数适中",但能不能听进去取决于模型实现,生成后要用网格统计验证
不建议在提示词里写具体版本号、具体面数阈值、具体品牌名,那些对几何形态几乎没有帮助,反而会带偏材质风格。
步骤 3:需要更高控制力时补参考图
只靠文字,同一个提示词每次生成的结果都会有差异。如果想固定轮廓,就要给参考图。
参考图的要求比想象中高:
- 纯白或纯色背景,背景和物体边界清晰
- 正交视角,不要明显的透视畸变,否则生成出来会变形
- 光照均匀,不要强侧光和硬阴影,阴影会被当成几何信息
- 如果支持多视图,就按正面、侧面、顶面各给一张
组织素材时按这个结构放,方便批量提交:
```text
asset_refs/
flashlight/
front.png
side.png
top.png
prompt.txt
```
prompt.txt 里放步骤 2 的那段结构化提示词。这样以后回看某个资产是怎么来的,一眼就能查。
步骤 4:一次生成多个候选,按硬指标筛
不要生成一次就用。同一提示词跑四到六个候选,然后按下面几条快速淘汰:
- 轮廓是否和描述一致,还是变成了一团
- 有没有明显的破洞和穿模
- 左右对称性如何
- 挂环、细杆这类结构是否还存在
- 表面有没有糊掉的贴图或者大面积纯色
这轮筛选只看一眼截图就能判断,不用打开编辑器。留下两到三个进下一轮。
步骤 5:导出模型文件
格式选择直接决定后面顺不顺。常见格式的差异:
| 格式 | 特点 | 适合场景 |
|---|---|---|
.glb | 单文件打包几何、材质、贴图 | 通用首选,网页和引擎都认 |
.gltf + .bin + 贴图 | 结构清晰,便于工具处理 | 需要程序化批处理时 |
.obj + .mtl | 兼容性广,但贴图容易丢 | 交给不支持 glTF 的老工具 |
.fbx | 动画和骨骼支持成熟 | 需要绑骨骼、走传统管线 |
.usdz | 苹果生态常用 | AR 快速预览 |
优先导出 .glb。导出时确认这几项:
- 勾选导出材质和贴图,不要只导几何
- 坐标系和单位按目标平台设置,glTF 使用 Y 轴向上、右手坐标系,Blender 使用 Z 轴向上,转换要在导出选项里处理
- 贴图分辨率按用途选,别默认拉满,文件会很大
导出后先看一眼文件体积。一个简单道具如果导出后有几 MB,多半是贴图分辨率过高或者面数失控。
步骤 6:落地体检与修复
拿到文件先做检查,别直接进编辑器。用 trimesh 跑一遍:
```python
import trimesh
mesh = trimesh.load("flashlight.glb")
print("面数:", mesh.faces.shape[0])
print("顶点数:", mesh.vertices.shape[0])
print("是否水密:", mesh.is_watertight)
print("包围盒:", mesh.bounds)
print("尺寸:", mesh.extents)
```
重点看三个数:
is_watertight为 False,说明网格有破洞,后续布尔运算和 3D 打印会出问题extents和规格表里的尺寸对不上,说明缩放需要修正- 面数远超预期,说明该做减面了
在 Blender 里做基础修复,按这个顺序操作:
1. 进入编辑模式,全选顶点,执行"合并按距离"(Merge by Distance),清掉重复顶点
2. 全选面,执行"重新计算外侧法线"(Recalculate Outside),修掉翻面的部分
3. 切到选择菜单,执行"选择非流形"(Select Non-Manifold),手动补洞
4. 用"分离 > 按松散块"(Separate by Loose Parts)看看这个模型是不是其实是好几块拼的
Blender 的 Python API 名称会随版本调整,写自动化脚本时以官方 Python API 文档当前版本为准。
步骤 7:重拓扑成可编辑网格
生成结果基本都是三角面。三角网格可以渲染,但很难编辑——想拉一条边加个倒角,会发现到处都是三角。
两条常用路线:
- 面数不算离谱、只想简化:加一个"精简"(Decimate)修改器,按比例降到目标面数,应用修改器
- 想要真正好编辑的四边形网格:用"重网格 > QuadriFlow 重网格"(Remesh > QuadriFlow Remesh),设定目标面数后重新生成
顺序很关键:先修破洞和法线,再重拓扑和减面。反过来做,破洞会被算法当成特征保留下来,更难处理。
重拓扑之后重新检查一次水密性和面数。这一步做完,模型才真正变成"可编辑资产"。
步骤 8:在 Blender 里做常规模块化编辑
到了这一步,剩下的就是普通建模操作了:
- 倒角:给边缘加"倒角"(Bevel)修改器,宽度小一点,能让硬表面看起来不那么假
- 镜像:如果只做了一半,加"镜像"(Mirror)修改器,勾选"合并"和"裁剪"
- 换材质:新建材质槽,用 Principled BSDF,把贴图连到基础色上
- 加细节:用布尔运算挖孔、切槽,注意布尔前先确认网格水密
- 摆原点:把原点设到物体中心或者底部,取决于后面要怎么摆放
改完之后执行一次"应用变换"(Apply Transform),把缩放和旋转烘焙进网格数据。这一步不做,后面拼进场景时会出现奇怪的缩放问题。
步骤 9:拼装进场景
把资产放进真实场景时,按这个清单逐项过:
```text
1. 单位统一:确认场景单位和资产单位一致
2. 朝向统一:确认资产的"正面"和场景约定的朝向一致
3. 命名规范:用 类别_名称_序号,例如 prop_flashlight_01
4. 分组管理:一个资产一个 Collection,不要平铺在场景根节点
5. 应用变换:位置、旋转、缩放全部应用
6. 导出设置:glTF 导出时勾选 +Y Up,让坐标系转换自动完成
```
如果场景里要放很多生成资产,建议先搭一个空场景,把标准尺寸的参考物体(一个人形方块、一扇门、一张桌子)放进去。新资产拖进来立刻就能看出比例对不对。
步骤 10:批处理与版本管理
资产变多之后,手动一个个导出会很累。可以用 gltf-transform 做命令行批处理:
```bash
npx @gltf-transform/cli optimize input.glb output.glb
```
这个命令会做合并、去重、贴图压缩之类的常规优化。具体可用的参数项以该工具当前文档为准。
配套的目录建议:
```text
assets/
source/ # 从 Astra 导出的原始文件,只读,不改
working/ # 在 Blender 里修的过程文件
final/ # 导出的最终 glb,直接给项目用
```
三份分开存的好处是,修坏了随时能从 source/ 重来。原始文件永远不要原地修改。
常见坑与排错
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 生成结果是一团糊在一起的形状 | 提示词描述了多个物体,或者缺少"单一物体"约束 | 拆成单独物体分别生成,再在场景里拼 |
| 挂环、细杆消失或断裂 | 细长结构在生成时被合并 | 提示词里强调保持连通,或单独生成后手动接上 |
| 导出的文件没颜色 | 导出时没勾选材质和贴图 | 重新导出,确认贴图路径可访问 |
| 拖进 Blender 后尺寸巨大或极小 | 单位不一致,或缩放没应用 | 执行应用变换,重新设置场景单位 |
| 编辑器里旋转卡顿 | 面数过高,几十万面级别 | 用精简修改器降到目标面数 |
| 贴图糊成一片纯色 | UV 重叠或者贴图分辨率不够 | 重新展开 UV,提高贴图分辨率后重导 |
| 布尔运算报错 | 网格不水密,有破洞或自相交 | 先补洞、合并重复顶点,再做布尔 |
| 导入引擎后朝向不对 | 坐标系没转换 | 导出时勾选 +Y Up,或在引擎导入设置里调整 |
下一步建议
走通一遍之后,可以顺着这几条线继续:
- 建提示词模板库。把跑出好结果的提示词按品类存档(硬表面道具、软体、建筑构件、植物),下次直接改写而不是从零写
- 做零件库。生成一堆同风格的螺丝、铰链、把手、接口,之后拼装复杂道具时直接调用,风格还统一
- 加骨骼和动画。需要动的部件(抽屉、门、机械臂)在 Blender 里手动加骨骼,比指望生成阶段出骨骼靠谱
- 做 LOD。同一个资产生成高、中、低三档面数,按摄像机距离切换
- 接进引擎。把
.glb导入 Unity 或 Unreal,配好材质节点和碰撞体,验证真实运行效果
整条链路里,花时间的地方通常不是生成,而是后面的修复、重拓扑和拼装。生成只是一个起点,把它当成"提供初始形状的实习生",后面的活还是要自己收尾。
