Add ModelTranslator tool design spec
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
c29c6f5bac
commit
609788fe00
@@ -0,0 +1,89 @@
|
||||
# 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、Roughness;AO 按贴图名匹配(含 `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` | TextureImporter:sRGB 开,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` | NativeFormatImporter,mainObjectFileID 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 工程验证材质/模型开箱可用(人工步骤)
|
||||
Reference in New Issue
Block a user