Files
AIC-Project/docs/superpowers/specs/2026-07-15-model-translator-design.md
T
2026-07-15 10:43:01 +08:00

90 lines
4.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ModelTranslator 工具设计文档
日期:2026-07-15
状态:已确认
## 目标
`Tools/ModelTranslator/` 下的 Python 工具:用 headless Blender 把带 PBR 贴图的 FBX(如 `src/tong.fbx`)转换为:
1. **纯模型 FBX**(剥离贴图,保留材质名/槽位)
2. **XPbr shader 所需贴图**(每材质一套,≤2048×2048):
- 基础贴图:RGB=颜色,A=透明 > AO > 255(自动判定)
- 混合贴图:RG=球面编码法线,B=金属度,A=粗糙度
3. **Unity 开箱即用资产**:贴图/材质/FBX 的 `.meta``.mat` 全部预生成,拷入 `Client/Assets/` 即可直接使用
## 环境
- Blender`D:\tools\blender-5.0.0-windows-x64\blender.exe`5.0),查找顺序:`--blender` 参数 → 环境变量 `BLENDER_EXE` → 上述默认路径 → PATH
- 外层 CLI 用系统 Python 3.12;图像处理在 Blender 内用 bpy + 自带 numpy,不引第三方依赖
## 文件结构
```
Tools/ModelTranslator/
model_translator.py # CLI 入口:找 blender、组命令行、汇报结果
bl_convert.py # Blender 内运行的转换脚本
README.md # 用法说明
src/ # 源 FBX(已存在)
out/<模型名>/ # 输出(git 忽略)
```
## CLI
```
python model_translator.py src/tong.fbx # 单文件
python model_translator.py src/ # 目录批量(*.fbx
[-o out] [--max-size 2048] [--blender <exe>]
```
## bl_convert.py 流程(每个 FBX
1. 空场景导入 FBX,解包全部内嵌贴图
2. 逐材质找 Principled BSDF,沿连线识别贴图:Base Color、Alpha、Normal(穿过 Normal Map 节点)、Metallic、RoughnessAO 按贴图名匹配(含 `ao`/`occlusion`/`ambient`,不区分大小写)
3. 目标尺寸 = min(max-size, 各源贴图最大边),所有参与贴图缩放到统一尺寸(`image.scale()`
4. 基础贴图:RGB=颜色贴图(无则 Principled 常量色);A=透明贴图 > AO 贴图 > 255
5. 混合贴图:
- RG=法线球面编码:切线法线 `n = rgb*2-1` 归一化后 `enc = n.xy/√(2(1+n.z)) × 0.5 + 0.5`;无法线贴图填 (0.5, 0.5)
- B=金属度贴图(取 R 通道)或 Principled 常量
- A=粗糙度贴图(取 R 通道)或 Principled 常量
6. 保存 RGBA PNG 到 `out/<模型名>/`
7. 删除材质中所有贴图节点,`path_mode='NONE'` 导出纯模型 FBX
8. 打印 JSON 摘要(stdout 标记行),runner 转为可读日志
## Unity 资产生成(model_translator.py 内完成,纯文本模板)
每材质:
| 文件 | 要点 |
|---|---|
| `<模型>_<材质>_base.png.meta` | TextureImportersRGB 开,maxTextureSize 2048 |
| `<模型>_<材质>_mix.png.meta` | TextureImporter**sRGB 关**(线性),maxTextureSize 2048 |
| `<模型>_<材质>.mat` | shader 引用 XPbr GUID(见下);`_MainTex`/`_MixTex` 引用预分配贴图 GUID;透明模式时写 keyword `_ALPHATEST_ON``_AlphaTest=1``_Metallic`/`_Roughness`/`_AO`=1.0 |
| `<模型>_<材质>.mat.meta` | NativeFormatImportermainObjectFileID 2100000 |
- XPbr shader GUID`cab897163f45445fa34263d6670bfc9e``Client/Assets/Game/shader/XShader/XPbr.shader.meta`,若该 meta 变更需同步工具常量)
- 模型 FBX 生成 `.meta`ModelImporter):`externalObjects` 按材质名重映射到生成的 `.mat` GUID,模型拖进场景直接生效
- 所有 GUID 用 `uuid4().hex` 预分配;同一模型重复转换时**复用已存在 meta 里的 GUID**(避免拷入 Unity 后再次转换导致引用断裂)
## 配套 shader 修改
`Client/Assets/Game/shader/XShader/XPbr_Base.hlsl``DecodeSphereMap` 入口加 `encoded = encoded * 2 - 1;`:现编码只能表示 xy≥0 的法线(无符号 rg),重映射后可表示全半球。只影响 XPbr(无存量资源),不动 XTex。
## 错误处理
- 找不到 Blender → 明确报错并提示 `--blender`
- 材质无 Principled BSDF → 警告,用全常量兜底(灰色、平面法线、金属 0、粗糙 0.5)
- 贴图输入是程序纹理/复杂节点 → 警告,用该输入的默认常量
- Blender 退出码非 0 → runner 透传 stderr 摘要
## 不做(YAGNI
合并图集/UV 重排、Cycles 烘焙、法线绿通道翻转选项(README 说明现状)、动画/骨骼处理(FBX 原样导出)。
## 验证
1. 实跑 `src/tong.fbx``src/woodcar.fbx`
2. 输出文件齐全,贴图尺寸 ≤2048
3. 法线 round-trip 校验:按 shader 公式解码生成贴图的 RG,与源法线角度误差 < 2°
4. 拷入 Unity 工程验证材质/模型开箱可用(人工步骤)