Add Nahida model import and preview pipeline

This commit is contained in:
2026-04-11 20:16:49 +08:00
parent 8f71f99de4
commit 030230eb1f
87 changed files with 7245 additions and 117 deletions

View File

@@ -0,0 +1,174 @@
# Nahida Unity式Model导入与Genshin卡通渲染正式化计划
日期2026-04-11
## 1. 目标
这一轮不再按“静态拆件预览”推进,而是正式切到更接近 Unity 的方案:
- FBX/OBJ 等外部模型统一作为 `Model` 主资产导入
- 场景侧通过 `Model -> GameObject hierarchy` 实例化恢复节点层级
- `Mesh` 继续只负责底层几何与 section/material slot
- Nahida 的卡通渲染改为“对齐 Unity 旧工程 `Genshin.shader` 语义”,而不是继续维持近似版 shader
本轮仍然明确不做:
- 骨骼动画
- GPU skinning
- `SkinnedMeshRenderer` 运行时
- BlendShape
- Animator / AnimationClip 播放系统
## 2. 当前判断
### 2.1 Model链路已经具备的能力
代码里已经有以下基础设施:
- `ResourceType::Model`
- `Model` / `ModelLoader`
- `xcmodel` artifact
- `AssimpModelImporter`
- `AssetDatabase``ModelImporter``Model` 为主资产导入
- sub-asset manifest 与 `LocalID -> artifact path` 解析
这说明“Unity式 Model 主资产”不是从零开始,而是缺最后几段关键闭环。
### 2.2 当前最主要的缺口
真正还没闭环的是:
1. `Model` 还不能正式实例化成场景层级
2. `MeshFilter/MeshRenderer` 还缺稳定的 sub-asset `AssetRef` 绑定入口
3. 编辑器侧还没有把模型资产当成“可实例化层级对象”来用
4. Nahida 当前 `XCCharacterToon.shader` 不是 Unity 旧工程 `Genshin.shader` 的等价移植
5. FBX 导入后的静态 mesh 目前丢失了 Unity shader 依赖的顶点语义,尤其是 `vertex color``UV1/backUV`
### 2.3 关于当前 shader 的明确结论
当前使用的是:
- `project/Assets/Shaders/XCCharacterToon.shader`
Unity 参考原件是:
- `docs/reference/NahidaUnity/Shaders/Genshin.shader`
- `docs/reference/NahidaUnity/Shaders/GenshinInput.hlsl`
- `docs/reference/NahidaUnity/Shaders/GenshinForwardPass.hlsl`
- `docs/reference/NahidaUnity/Shaders/GenshinOutlinePass.hlsl`
当前 shader 只是第一版近似实现,不是原 shader 原样移植。当前效果发怪,核心原因不是简单调参,而是语义缺口:
1. 没有按 Unity 的 `_IS_FACE / _SPECULAR / _RIM / _NORMAL_MAP / _DOUBLE_SIDED` 关键字分支工作
2. 面部阴影没有按 `_FaceDirection + _FaceLightMap + _FaceShadow + _FaceShadowOffset` 的逻辑算
3. 阴影 ramp 还没有按 Unity 的 material ID 分层抽样
4. specular 还不是 Unity 那套 `lightMap + metalMap + matcap` 路径
5. rim 不是基于 scene depth 的 URP 风格边缘检测
6. outline pass 还没有正式接回 `Nahida_Body_Smooth.mesh` 与 outline color 分档逻辑
7. Unity 里还有 `MaterialUpdater.cs` 在运行时写 `_FaceDirection`,当前引擎里这条驱动链不存在
8. 更关键的是,当前引擎导入出的 Nahida mesh 只有 `Position/Normal/Tangent/Bitangent/UV0`,缺 `Color/UV1`
9. Unity 的 `GenshinForwardPass.hlsl` 明确依赖 `input.color.r``backUV`
10. 这会直接破坏 body/hair 分支的 `aoFactor = lightMap.g * input.color.r` 与双面材质背面采样,因此“脸基本对、身体和头发大面积偏色”是符合代码现状的结果
所以它现在看起来不像原工程,是正常结果。
## 3. 本轮正式范围
### Phase 1Model实例化基础链路
目标:
-`Model` 正式实例化为场景 `GameObject` 层级
任务:
-`MeshFilterComponent` 增加 mesh sub-asset `AssetRef` 绑定入口
-`MeshRendererComponent` 增加 material sub-asset `AssetRef` 绑定入口
- 保证这些 sub-asset 引用能被场景序列化稳定保存
- 新增 `Model -> Scene hierarchy` 实例化工具
- 恢复节点本地 TRS
- 恢复 mesh binding 与 material slot binding
验收:
- 导入一个 `OBJ/FBX Model` 后,可以在场景里创建出层级对象
- 场景存盘后 sub-asset 引用不丢
- 不需要把 FBX 拆成手工摆放的多个静态对象
### Phase 2编辑器侧 Model使用工作流
目标:
- 让编辑器把 `Model` 当成 Unity 式模型资产使用
任务:
- 增加“从模型资产创建场景对象”的命令入口
- 后续接到 Project/Hierarchy/Viewport 的拖拽放置链路
- 让 Nahida 预览场景切到 `Model` 驱动的实例化路径
验收:
- 编辑器里不再主要依赖“手工往 `MeshFilter` 塞 FBX 路径”
- Nahida 预览对象结构来自 `Model` 实例化,而不是手工拆件
### Phase 3Genshin shader 语义对齐
目标:
- 让 Nahida 使用更接近 Unity 旧工程的卡通渲染语义
任务:
- 先补齐静态 mesh 顶点语义链路:`Color``UV1/backUV`
- 让前向渲染输入布局与 `XCCharacterToon.shader` 能真正接到 `COLOR``TEXCOORD1`
- 恢复 body/hair 分支里的 `lightMap.g * input.color.r`
- 恢复双面材质对 `backUV` 的切换采样
- 按 Unity 原 shader 拆分 forward / outline 两条主路径
-`_IS_FACE / _SPECULAR / _RIM / _NORMAL_MAP / _DOUBLE_SIDED` 语义
- 补 face shadow 正式逻辑
- 补 outline pass 与 `Nahida_Body_Smooth.mesh`
- 视情况补一个轻量 `_FaceDirection` 运行时驱动
验收:
- 角色明暗分层、面部阴影、描边、头发高光接近 Unity 参考
## 4. 执行顺序
这一轮按下面顺序推进:
1. 先补 `Model` 实例化与 sub-asset 引用闭环
2. 再把 Nahida 预览场景切到 `Model` 路径
3. 再补 FBX 静态 mesh 的 `Color/UV1` 导入、artifact 保存、渲染输入布局与 shader 接线
4. 再做 shader 语义对齐
5. 最后做画面调参与残余语义收口
不能反过来做。因为当前 shader 再怎么调,只要场景组织和资源绑定语义不对,结果都不稳定。
## 5. 当前这一刀
这一轮立刻执行的第一刀是:
- 补齐 FBX 静态 mesh 的 `vertex color``UV1/backUV` 导入
-`BuiltinForwardPipeline``XCCharacterToon.shader` 真正吃到 `COLOR/TEXCOORD1`
- 补 Nahida 集成诊断与回归验证,先把 body/hair 的基础色输入纠正
- 在这个基础上继续向 Unity 式 `Model -> hierarchy` 与完整 shader 语义收口推进
这是 Nahida 当前从“基础贴图都不稳定”切回“先保证静态基础颜色正确”的前置条件,也是后续继续 Unity 式正式方案的必要补丁。
## 6. 2026-04-11 新发现补充
在实际跑 `tests/Rendering/integration/nahida_preview_scene` 之后,问题又进一步收窄了:
- Nahida 的 `Body_Mesh0` 运行时已经有 `uv1` 数值,且当前实现会在缺少第二套 UV 时回填 `uv1 = uv0`
- 但导入器只在 `mesh.HasTextureCoords(1)` 为真时才打 `VertexAttribute::UV1` 标记
- 结果就是:数据层面有 fallback `uv1`,语义层面却仍被当成“没有 UV1”
- 这会导致后续依赖 `backUV` 的 shader / 诊断逻辑继续走错分支
因此当前这一刀的执行重点再精确一步,变成:
1. 修复 `AssimpModelImporter` / `MeshLoader` 中“fallback uv1 已写入但 `UV1` flag 未置位”的不一致
2. 提升 `ModelImporter` 版本,强制 Nahida 现有 `.xcmodel` artifact 重导
3. 补针对 Nahida FBX 的导入回归测试,确保 `UV1` fallback 与 `Color` 语义不会再次退化
4. 再继续跑 Nahida 集成图验证 body/hair 基础色是否进一步收敛