MetaCore/docs/designs/metacore-material-import-integration-design.md

9.5 KiB
Raw Blame History

MetaCore 材质系统与模型导入衔接设计

生成时间2026-03-28
状态:草案
范围M2 资源与模型导入循环、M3 场景编辑、材质与光照工作流

目的

这份文档用于解决一个关键衔接问题:

  • 模型导入后,材质信息如何进入 MetaCore
  • MetaCore 内部材质资源应该长什么样
  • 场景对象如何引用材质
  • 第一阶段如何接入 panda3d-simplepbr

如果这条链不先设计清楚后面模型导入、Inspector 编辑、场景保存、Player 渲染都会各做各的,最终一定返工。

结论先说

MetaCore 第一阶段应采用下面这条链路:

源模型文件 -> 导入文档 -> 网格资源 / 材质资源 -> 场景对象 MeshRenderer -> simplepbr 参数映射 -> Player 渲染

这里必须明确两件事:

  1. 模型导入负责“生成 MetaCore 自己的资源”
  2. 渲染后端只负责“消费 MetaCore 材质资源”

不能让模型文件直接决定运行时材质结构,也不能让 simplepbr 反向决定 MetaCore 材质资源长什么样。

当前代码库现状

从当前仓库看,已经具备下面的基础:

  • 资产元数据与资产数据库骨架
  • 导入服务接口与 cook 接口
  • 包格式与二进制读写能力
  • MeshRenderer 组件基础
  • MeshRenderer.BaseColor
  • MeshRenderer.Visible

但当前还缺:

  • 正式的材质资源类型
  • 正式的网格资源类型
  • 模型导入后的材质槽映射定义
  • 场景对象对材质资源的引用方式
  • 材质 Inspector 与资源编辑流程
  • 材质到 simplepbr 的统一映射层

因此当前最合理的做法不是直接继续加渲染效果,而是先把资源和组件关系定清楚。

第一阶段总链路

flowchart LR
    A["源模型文件 (.glb/.gltf/.fbx)"] --> B["导入器"]
    B --> C["导入结果文档"]
    C --> D["网格资源 (.mcasset/.mcmesh)"]
    C --> E["材质资源 (.mcasset/.mcmat)"]
    D --> F["场景对象 MeshRenderer"]
    E --> F
    F --> G["MetaCore 渲染抽象层"]
    G --> H["simplepbr 参数映射"]
    H --> I["Player 渲染输出"]

第一阶段资源分层

1. 源资源

这是项目中由用户导入的原始文件:

  • .glb
  • .gltf
  • .fbx
  • 后续 .obj

这些文件是输入,不是 MetaCore 运行时直接消费的最终资源。

2. 导入结果文档

导入器解析源文件后,生成一份导入结果文档,用于表达:

  • 导入得到几个网格资源
  • 导入得到几个材质资源
  • 每个网格默认使用哪个材质槽
  • 原始节点层级如何映射
  • 原始命名如何保留

这份文档属于导入中间层,主要为导入器、重导入和调试服务。

3. MetaCore 正式资源

第一阶段至少应该落两类正式资源:

  • Mesh Asset
  • Material Asset

后续再扩:

  • Texture Asset
  • Model Asset
  • Material Instance Asset

第一阶段推荐资源模型

Mesh Asset

Mesh Asset 第一阶段最少应包含:

  • 资源 GUID
  • Mesh 名称
  • 顶点数据
  • 索引数据
  • 法线
  • UV0
  • 切线
  • 包围盒
  • SubMesh 列表
  • 每个 SubMesh 对应的默认材质槽索引

如果一个模型含多个材质槽,应该通过 SubMesh -> MaterialSlotIndex 关系表达,而不是把整个模型强行压成一个材质。

Material Asset

Material Asset 第一阶段最少应包含:

  • 资源 GUID
  • 材质名称
  • 材质类型
  • BaseColor
  • BaseColorTexture
  • NormalTexture
  • Metallic
  • Roughness
  • MetallicRoughnessTexture
  • EmissiveColor
  • EmissiveTexture
  • AoTexture
  • AlphaMode
  • AlphaCutoff
  • DoubleSided

第一阶段不要求复杂 shader graph但必须保证这个资源结构已经是 MetaCore 自己的,不是 simplepbr 参数字典。

Texture Asset

如果当前阶段不想单独做完整纹理资源编辑器,也至少要有稳定纹理资源记录,用于:

  • BaseColorTexture
  • NormalTexture
  • MetallicRoughnessTexture
  • EmissiveTexture
  • AoTexture

第一阶段可以先把纹理当成辅助资源,由材质资源引用。

模型导入后的材质映射规则

这是第一阶段最重要的设计点之一。

规则 1导入器保留源模型的材质槽

例如一个源模型含 3 个材质槽,导入后应保留:

  • SubMesh 0 -> Material Slot 0
  • SubMesh 1 -> Material Slot 1
  • SubMesh 2 -> Material Slot 2

不能在第一阶段就把它们合并掉。

规则 2每个源材质生成一个 MetaCore Material Asset

也就是说,导入器不只是读材质参数,而是正式创建:

  • Valve_Body.mcmat
  • Valve_Handle.mcmat

类似这样的材质资源。

这样后面 Inspector、资源浏览、复用和重导入才有稳定对象可操作。

规则 3导入器负责参数归一化

第一阶段推荐优先按 glTF 语义归一化:

  • BaseColor
  • BaseColorTexture
  • Metallic
  • Roughness
  • MetallicRoughnessTexture
  • NormalTexture
  • Emissive
  • DoubleSided
  • AlphaMode

对于 FBX 等不完全一致的格式,第一阶段允许做保守映射,但输出必须仍然变成同一套 MetaCore 材质结构。

规则 4重导入默认保留资源身份

重导入时应尽量保持:

  • 材质资源 GUID 不变
  • 网格资源 GUID 不变

否则场景对象和 prefab 的引用会被打断。

第一阶段推荐的组件模型

当前 MeshRenderer 只保存:

  • BuiltinMesh
  • BaseColor
  • Visible

这不足以支撑真实模型和材质工作流。

第一阶段应逐步演进为:

  • MeshAssetGuid
  • MaterialAssetGuids
  • Visible
  • 必要时保留调试型覆盖参数

推荐结构

第一阶段建议 MeshRenderer 具备:

  • 一个 MeshAssetGuid
  • 一个 std::vector<MetaCoreAssetGuid> 用于材质槽引用
  • 一个 Visible

如果 SubMesh 数量和 MaterialAssetGuids 数量不一致,应在 Editor 和 Cook 阶段报错或警告。

不建议的做法

第一阶段不要继续把材质核心参数直接塞在 MeshRenderer 组件里。

BaseColor 作为调试或临时覆盖参数还能容忍,但长期必须迁回正式材质资源。

Inspector 工作流建议

第一阶段材质编辑工作流应分成两层:

1. 对象级 Inspector

用于编辑:

  • 当前对象引用哪个 Mesh
  • 当前对象每个材质槽引用哪个 Material
  • 是否可见

这一层主要做“资源指派”。

2. 材质资源 Inspector

用于编辑:

  • BaseColor
  • 贴图槽
  • Metallic / Roughness
  • Emissive
  • AlphaMode
  • DoubleSided

这一层主要做“资源参数编辑”。

不要把“对象引用”和“材质内容”全部混在同一个对象 Inspector 里。

与 simplepbr 的衔接方式

第一阶段 simplepbr 应只出现在渲染映射层。

也就是:

  • MetaCoreMaterialAsset -> MetaCoreRenderMaterialParams -> Panda3D / simplepbr

第一阶段最小映射

应至少支持:

  • BaseColor
  • BaseColorTexture
  • NormalTexture
  • Metallic
  • Roughness
  • EmissiveColor
  • EmissiveTexture
  • DoubleSided

明确不要做

第一阶段不要把 simplepbr 的内部参数名、调用方式、配置细节直接暴露到:

  • 材质资源格式
  • Editor Inspector
  • 场景组件结构

否则后面替换渲染后端时,整条链都要重写。

首批格式建议

P0glTF / .glb

这是第一阶段最应该优先打通的格式。

原因:

  • 现代
  • 对 PBR 语义支持较清晰
  • 与材质参数映射天然更顺
  • 适合作为数字孪生模型导入起点

P1FBX

可以作为第二优先级。

原因:

  • 现实项目里经常遇到
  • 但材质与层级语义更杂
  • 更容易出现导入归一化问题

P2OBJ

只建议作为补充格式,不建议第一阶段主打。

原因:

  • 表达能力弱
  • 对现代 PBR 工作流支撑差

保存与打包建议

第一阶段推荐:

  • 项目内保留源文件
  • 导入后生成材质/网格正式资源
  • Scene 保存时只引用资源 GUID
  • 打包时由 cook 收集依赖资源

不要让 Scene 直接内嵌整份材质内容。

这对后面:

  • 资源复用
  • 场景共享
  • 材质统一替换
  • 打包依赖分析

都更健康。

错误与诊断要求

第一阶段至少要能发现这些问题:

  • 模型导入缺失材质槽
  • 材质引用的纹理丢失
  • 场景对象引用了不存在的 Mesh
  • 材质槽数量与 SubMesh 数量不匹配
  • 材质参数无法映射到当前后端

这些问题应至少在:

  • 导入阶段
  • Inspector
  • Cook 阶段

给出明确提示。

推荐实现顺序

建议按下面顺序推进:

  1. 定义 Material Asset 资源结构
  2. 定义 Mesh Asset 资源结构
  3. 扩展 MeshRenderer,让它引用资源 GUID
  4. 先打通 glTF/.glb -> Mesh/Material Asset
  5. 打通对象级 Mesh/Material 指派
  6. 打通材质资源 Inspector
  7. 建立 Material -> simplepbr 映射层
  8. 验证 Editor 与 Player 一致性
  9. 再考虑 FBX 与重导入增强

与第一阶段主线的关系

这份设计属于:

  • M2 资源与模型导入循环
  • M3 场景编辑、材质与光照工作流

它的意义是把这两段主线真正接起来。

如果没有这份衔接设计M2 和 M3 会变成两个独立子系统:

  • M2 只能“导进来”
  • M3 只能“手工调颜色”

这不是一个真正可用的引擎工作流。

最终建议

第一阶段最合理的策略不是:

  • 直接做完整 URP
  • 也不是继续把材质逻辑散落在 MeshRenderer

而是:

先建立 MetaCore 自己的 Mesh/Material 资源体系,再把模型导入和 simplepbr 渲染后端挂到这套资源体系两端。

这是让 MetaCore 真正形成“模型导入 -> 材质编辑 -> 场景搭建 -> Player 渲染”闭环的关键一步。