- docs/MIDREVIEW.md: what M0'-M2.5 proved, bridge-layer LOC (~1100), key technical conclusions (4x4 transpose, animation method B, no handedness flip needed), remaining risks, recommendation = enter Phase 2 with a 3-item wrap-up (compare.py, dump_materials oracle, refocused perf). - harness MTGODOT_STRESS=N: grid of N animated warriors, vsync off, dumps test/godot-macos-stress.json. Frame times are throttle-capped in a background window (~30fps to 50 chars, 52ms at 100); the reliable signals are build cost ~165ms/char and the 100-char breakout. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WaHYEY9rwLWt21PULiYjeJ
6.2 KiB
6.2 KiB
Phase 1 中期评审 — mtgodot-poc
日期:2026-08-29 · 平台:macOS(Apple M2)· Godot 4.7.1 · 对标
GODOT-POC-PLAN.md§00 Phase 1 结论先行:桥接层工程量小、风险已基本出清,建议进入 Phase 2(移动端)。M2.5 门禁的"材质精确映射"仍有一处需要 oracle 的开口,不阻塞。
1. 做到了什么(M0'–M2.5)
| 里程碑 | 状态 | 证据 |
|---|---|---|
| M0' 脚手架 | ✅ | GDExtension 加载、Metin2Model/Metin2AnimPlayer 注册、libgr2 静态链接、Godot 4.7 工程 Metal Forward+ 出画 |
| M1 静态渲染 | ✅ | warrior_cheongrin:75 骨 / 5 表面 / 3324 顶点,正立、朝 +Z、unit_scale=0.01、flip_z/flip_winding=false、贴图正确(test/golden/m1-bindpose.png)。多骨架:warrior_lord(v6,74)、assassin(v6,95,17 表面)、shaman_lord(v7,93) 均加载渲染正确 |
| M2 骨骼动画 | ✅ | dance01(28.3s / 74 track)经 gr2::sample_pose(跨文件)→ Skeleton3D.set_bone_global_pose → Godot GPU 蒙皮播放。selfcheck 25 采样 0 NaN/Inf。t=9/16 姿势正确、无蒙皮撕裂(test/golden/m2c-*.png、m25-warrior-shader.png) |
| M2.5 材质与观感 | 🟡 门禁未闭 | ShaderMaterial(modulate tex×COLOR×light;opaque/alpha/alpha-test/add 四模式)+ 目录扫描贴图解析(warrior 5/5、assassin 17/17、shaman 1/1 表面命中)+ 方向光阴影 + procedural sky + 引擎雾(test/golden/m25-*.png)。libgr2::dump_materials() 已加(见 §4) |
2. 桥接层工程量(实测)
新增 C++ ≈ 1100 行(含端口自 xrender-poc 的 DXT 解码 160 行):
| 文件 | 行 | 职责 |
|---|---|---|
gr2_bridge.{h,cpp} |
~260 | gr2 Mat4→Transform3D(4×4 转置)、build_skeleton/build_skin/build_mesh、Z-up→Y-up make_conv |
metin2_model.{h,cpp} |
~470 | Metin2Model 节点、load_gr2、贴图解析、材质、属性 |
metin2_anim.{h,cpp} |
~230 | Metin2AnimPlayer、每帧 sample_pose→骨骼、selfcheck |
m2_material.{h,cpp} |
~130 | Metin2 风格 ShaderMaterial(两个 shader:blend_mix / blend_add) |
dxt.{h,cpp} |
~160 | DDS DXT1/3/5 软解(端口) |
libgr2 gr2_material.cpp(xrender-poc) |
~110 | dump_materials() 类型树遍历(附加) |
耗时:M0'–M2.5 一次会话内跑通。与计划 §05 估的 Phase 1「3.5–5 周单人」相比,核心桥接远比预估轻 —— 因为 libgr2 已完成、Godot 的 Skeleton3D/ArrayMesh/Skin/GPU 蒙皮直接可用,且关键恒等式(skin_matrix = global_pose(i)·bind_pose(i) == gr2 deformer 矩阵)成立,不需要自研蒙皮。剩余预估工作量集中在 M2.5 材质精修 + 对拍。
3. 关键技术结论
- 坐标/单位:gr2 行主序 Mat4 → Godot
Transform3D就是一次 4×4 转置(gr2 平移在第 4 行 = Godot.origin)。Z-up cm → Y-up m(rotate(-90°,X)+scale(0.01))放在Metin2Model节点自身 transform。四个测试骨架全部flip_z=false、flip_winding=false正确 —— Metin2/Granny 内容对 Godot 右手系不需要额外镜像。 - 动画走 B 方案:
_process里sample_pose出world[],skel.set_bone_global_pose(i, conv(world[i])),Skin bind =conv(inverse_world[i])。Godot 的 GPU 蒙皮矩阵global_pose(i)·bind(i)恒等于 gr2 deformer 矩阵。不需要烘焙Animation资源 即可保真(A 方案仅在移动端多角色 CPU 压不住时才需要)。 - 贴图:Godot 4
Image.load()不支持.dds→ 运行时软解 DXT(dxt.cpp)。.gr2用.gdignore+ 绝对路径加载,绕开 Godot import。 - 移动端预判更好:M2.5 的
ShaderMaterial+ArrayMesh+Skeleton3D都在 Godot Compatibility(GLES3) 支持范围内 —— Phase 2 老安卓机兜底比"Godot 里塞自研渲染器"那条路好。
4. 剩余风险 / 门禁开口
| 项 | 影响 | 出路 |
|---|---|---|
| M2.5 材质精确映射未闭(唯一门禁开口) | libgr2::dump_materials() 已能取材质名 + FromFileName(warrior 4 材质 / 2 有 diffuse 名),但 material_index→贴图 的映射未对拍 Granny,实测驱动 warrior 时 body 表面误取 face 贴图。当前默认走文件名+目录扫描启发式(观感正确),material 路径 use_gr2_materials 开关默认关 |
需要 Granny oracle 逐材质对拍(与 xrender-poc M1 T5 同一缺口,共用修法)。这是 Phase 1 收尾的最后一项 |
| 对拍未接线 | 与 xrender-poc bgfx demo / oracle 的逐帧几何/骨骼矩阵对拍脚本(test/compare.py)未写 |
需先构建 xrender-poc bgfx demo(首次 ~10 min)。中期评审后、进 Phase 2 前补 |
| 性能数字被节流 | 后台窗口下 Godot 限 30fps,1–50 角色帧时间都贴在 33ms 天花板;100 角色破顶到 52ms。资产构建 ~165ms/角色(单线程,无跨模型缓存),100 角色加载 16.5s(test/godot-macos-stress.json) |
真机 / 前台窗口下重测(Phase 2)。构建成本需 Phase 2 做多线程 + eterpack 共享贴图 |
| 多材质槽内拆分 | build_mesh 目前一个 gr2 mesh = 一个 surface,未按 tri_groups[].material_index 再拆 |
有 material API 对拍后一起做 |
| ShaderMaterial 静态 Shader 退出泄漏、alpha 排序 corner case、法线未逆转置 | 均为已知小项,见 GODOT-POC-PLAN.md §M2.5 T2.5.6 |
不阻塞 |
5. 建议
进入 Phase 2(iOS + Android)。
理由:Phase 1 要证明的三件事里,①gr2→Godot 场景对象、②动画运行时移植,已用可运行代码 + 截图 + 0-NaN 自检证明可行且工程量小;③观感还原的基础设施(自定义 shader、阴影、sky、fog、多骨架)已就位,只差"材质精确映射"这一处需 oracle 的收尾,不构成方案性风险。
Phase 2 前的收尾清单(1–1.5 周):
- 写
test/compare.py,与 xrender-poc bgfx demo 同机位 / 同 t 对拍几何 + 骨骼矩阵。 - 补
libgr2::dump_materials的 Granny oracle 对拍,闭合 M2.5 门禁。 - 前台窗口 / 真机重测性能,给 Phase 2 的动画 A/B 一个可信基线。
不建议现在做的:地形、.mse 特效、eterpack、UI/Python —— 均按计划留到正式移植。