shenandshen c3a6fb973e fix(rendering): checkpoint main-character recovery and visual regression work
Handle late main-character data, guarded model construction, bounded retries and map correction. Validate player model sources and add lifecycle and real-asset visual regressions.

Include pending material and character-selection changes, updated A1 screenshot, and the detailed rendering repair plan. Hair occlusion, full UI parity and final macOS package acceptance remain unfinished.
2026-09-08 08:52:30 +08:00
2026-08-31 20:04:32 +09:00
2026-09-07 14:53:36 +08:00
2026-09-07 14:53:36 +08:00
2026-09-01 18:49:28 +09:00
2026-09-07 14:53:36 +08:00
2026-09-07 14:53:36 +08:00
2026-09-07 14:53:36 +08:00

mtgodot-poc

Godot 4 + 自研资源 loader」跨平台方案的渲染 Demo。 用一个 C++ GDExtension 把 Metin2 的 .gr2 骨骼资源渲染进 Godot,用 Godot 内置渲染器。

2026-08-29:并入 xrender-poc 原先与本仓库并行的 bgfx 自研引擎方案(xrender-poc 经中期评审(docs/MIDREVIEW.md停止开发,其可复用部分—— libgr2gr2 v6/v7 读取器,已对拍 Granny)、formats.msa/.msm)、oracleGranny 真值工具)、 toolslibgr2 校验工具)、docs/reference(格式逆向笔记)——已 vendored 进本仓库。 bgfx 侧的渲染器 / 平台壳 / 第三方库全部弃用(Godot 取代)。bgfx demo 的参考截图留在 test/bgfx-reference/ 供交叉核对。xrender-poc 目录本身已删除(2026-08-30)。

自用项目(内部研究,不对外发布),分两阶段推进:

阶段 平台 里程碑 产出
Phase 1(当前) macOS M0' · M1 · M2 · M2.5 中期评审
Phase 2 Android(一加 13 / Vulkan)· iOSiPhone 16 / Metal M3 三设备各一次 bring-up + 性能留档

自用、不对外发布,无正式 go/no-go 门禁;三台目标设备都是现代硬件,全程不涉及 GLES3 / Compatibility 渲染器,不做中低端 / 老机器。

完整计划见 docs/GODOT-POC-PLAN.md;离可用客户端还差什么见 docs/BACKLOG.md(分层未完成清单);把参考图那种整张地图画面做出来的实施规格见 docs/SHINSOO-WORLD-RENDERING.md(正式移植,Phase 2 bring-up 之后); 距参考图「目视等价」还差哪些保真化工作见 docs/PARITY-GAP.md

当前进入游戏、模型/发型、贴地与技能栏问题的分阶段修复步骤,以及结合两个 Godot 项目的 对照验证和 macOS 包验收要求,见 docs/RENDERING-REPAIR-PLAN.md 2026-09-08,实施计划;不表示其中工作已完成)。


现状

  • M0' — 脚手架。GDExtension 加载 + Metin2Model 注册 + libgr2 链接可调用
    • Godot 4.7 工程经 Metal Forward+ 出画。T0.4 实际 export 待装 4.7.1 导出模板。
  • M1 — 静态渲染。gr2Skeleton3D + ArrayMesh + Skin + 材质。 warrior_cheongrin75 骨 / 5 表面 / 3324 顶点)正立、朝 +Z、贴图正确 (test/golden/m1-bindpose.png)。多骨架:warrior_lord(v6,74)、assassin(v6,95,17 表面)、 shaman_lord(v7,93) 均正确加载渲染。
  • M2 — 骨骼动画。Metin2AnimPlayer _processgr2::sample_pose(跨文件) → 默认 CPU 线性混合蒙皮(把 libgr2 的 Σ w·invWorld·world 直接作用到顶点,每帧重建 mesh)。 get_bone_global_pose vs conv(world) 全骨 ≤2.6e-5selfcheck 0 NaNdance_1 等所有动作 头/护甲/躯干正确,与 xrender-poc bgfx demo 一致。 MTGODOT_GPUSKIN=1自写蒙皮顶点着色器m2_material SRC_SKIN:逐骨完整 4×3 矩阵 存 RGBAF 纹理,绕过 Skeleton3D —— Godot 内置 GPU 蒙皮会正交化、丢 Granny 烘在 rig 骨上的 shearwarrior 7 根 / sura 16 根,见 test/shear-bones-survey.md)。人群场景用它。 .msaanim_path.msa → motion .gr2 + Accumulation + MotionEventData get_events() / motion_event 信号,带循环回绕)+ LoopData 元数据;播放器 loop=false 可播一次并发 playback_finished(片段循环次数执行仍在 backlog C4)。 .msmgr2_path.msm → 自动加载 BaseModelFileName(含散包目录扫描)+ get_hair_options() 发型目录(发型 mesh 挂接留 Phase 2)。
  • M2.5 — 材质与观感保真。ShaderMaterialmodulate tex×COLOR×light、 opaque/alpha/alpha-test/add 四模式)+ 方向光阴影 + procedural sky + 引擎雾。 贴图走 gr2 material 绑定build_parts()tri_groups[].material_index 把一个 gr2 mesh 拆成多个 Godot surface,各 surface 取 Mesh::material_textures[matidx]mesh-local)→ 同目录大小写不敏感查 .dds;找不到才回退文件名启发式。shaman(1→2 面)/assassin(17→18 面) 各面贴图正确。MODULATE2X 等 stage op 仍只近似(差距清单见 docs/GODOT-POC-PLAN.md §M2.5 T2.5.6)。
  • [~] 中期评审docs/MIDREVIEW.md。结论:桥接层工程量小、 风险基本出清,建议进入 Phase 2compare.py 已有进程/截图/结构硬门禁,像素差仍为 advisory;收尾重点是前台/真机性能重测与桥接层全语料 draw 冒烟(默认已是 CPU LBS)。

50 角色压力采样:test/godot-macos-stress.json(后台窗口 30fps 节流,仅构建成本 ~165ms/角色 和 100 角色破顶到 52ms 是可信信号)。


环境

组件 版本 / 位置 说明
Godot 4.7.1/opt/homebrew/bin/godotHomebrew cask 编辑器 + headless
godot-cpp submodule extension/godot-cpp @ 101ae38034304346a46ea9ea84ae156d3e860496 精确 gitlink 锁定(.gitmodules 不跟踪移动分支);bundled extension_api-4-7.json
Xcode 26.4.1 macOS 构建
CMake 已装;不需要 SCons godot-cpp 走 CMake 路径
libgr2 / formats / oracle / tools vendored 进本仓库 见下「vendored 库」

导出模板M0' T0.4 / 真正 export 才需要):编辑器内 Editor → Manage Export Templates → Download,或 godot --headless --install-export-templates。~600MB,版本须与编辑器一致(4.7.1)。


构建

git submodule update --init --recursive     # 拉 godot-cpp(首次)
./build.sh                                   # Debug;产物 → project/bin/libmtgodot.macos.template_debug.dylib
./build.sh Release                           # template_release

首次会编译 godot-cpp(几分钟)。扩展构建自动带上 vendored libgr2 + formats

只想构建 libgr2 / formats / 校验工具(不碰 godot-cpp):

cmake -B build-tools -DMTGODOT_BUILD_EXTENSION=OFF -DMTGODOT_BUILD_TOOLS=ON
cmake --build build-tools -j8
./build-tools/tools/gr2fuzz  "$PWD/assets"   # 全量解析冒烟
./build-tools/tools/gr2dump  <file.gr2>

运行

# 完整客户端:登录 → 选人 → 进游戏(用仓库内 assets/)
./run-client.command                          # 或双击
#   = MT_ASSETS=$PWD/assets godot --path project res://client_main.tscn

# 打包 .app(需先装 Godot 4.7.1 macOS 导出模板)
./build-macos-client.sh [debug|release]       # -> build/export/mtgodot-poc.app

# 编辑器打开
godot -e --path project

# 模型查看器 harness(旧 main_scene
godot --path project res://main.tscn

# headless 冒烟测试(验证 GDExtension 加载 + 类注册)
godot --headless --path project --quit-after 3

# 跑一个真实 gr2 过 libgr2(可选)
MTGODOT_PROBE_GR2="$PWD/assets/PC/ymir work/pc/warrior/warrior_cheongrin.gr2" \
  godot --headless --path project --quit-after 3

控制台出现 [mtgodot] Metin2Model registered OK — libgr2 linked; ... = M0' 的 T0.1/T0.2 通过。

窗口内:拖拽 = 轨道,滚轮 = 缩放,F2 = 截图(→ user://)。


vendored 库(并入自 xrender-poc2026-08-29

目录 内容 谁用
libgr2/ gr2 v6/v7 只读读取器(header/section/Oodle1/类型树/骨架/网格/曲线/材质)。零第三方依赖。9166 语料 fuzz 0 崩溃;bind pose + 蒙皮对拍 Granny 2.9.12 ≤6.5e-5。含 dump_materials() extensionxrender::libgr2)、tools
formats/ .msa(动作)/ .msm(模型 + 发型)/ textscript 解析。 M2 T2.2/T2.3 起(retarget + motion event
oracle/ Wine + MinGW 交叉编译的 Granny 真值工具(oracle.c + 脚本 + RUNBOOK.md)。oracle.exe / granny2_x64.dll 不入库(体积 + RAD IP),build-wine.sh 本地重建。 M2 数值门禁、M2.5 材质对拍
tools/ gr2dump(转储)/ gr2fuzz(全量解析冒烟)/ oracle_difflibgr2 vs oracle 逐字段对拍)/ anim_probe(每骨 world 3×3 的 det/shear/scale 探针,查蒙皮走样)。 libgr2 回归
docs/reference/ xrender-poc 的格式逆向笔记(M0M4 施工文档 + PLAN)。见 docs/reference/README.md 查格式细节
test/bgfx-reference/ bgfx demo 的参考截图 + noise_floor.json / m2-numeric.json / assets.list 基线。 与 Godot 输出交叉核对

CMake:顶层 add_subdirectory(libgr2) + add_subdirectory(formats)(跨平台,不碰 godot-cpp); extensiontarget_link_libraries(... xrender::libgr2)tools-DMTGODOT_BUILD_TOOLS=ON 开启。

libgr2/README.md 里的 oodle1.c clean-room 提醒依然适用:src/oodle1.c 是泄露 SDK 端口, 仅限内部研究 / 非发布 / 非商用;对外发布前必须 clean-room 重写。


目录

mtgodot-poc/
  CMakeLists.txt              顶层:add_subdirectory(libgr2/formats/[tools]/[extension])
  build.sh                   便捷构建(扩展)
  libgr2/                     ← vendoredgr2 读取器(xrender::libgr2
  formats/                    ← vendoredmsa/msm/textscript
  oracle/                     ← vendoredGranny 真值工具(exe/dll 不入库)
  tools/                      ← vendoredgr2dump / gr2fuzz / oracle_diff
  extension/
    CMakeLists.txt           mtgodot SHARED + godot-cppconsume xrender::libgr2
    godot-cpp/               submodule @ 101ae38034304346a46ea9ea84ae156d3e860496
    src/
      register_types.{h,cpp} GDExtension 入口
      metin2_model.{h,cpp}   gr2 → Skeleton3D + ArrayMesh + Skin + 材质
      metin2_anim.{h,cpp}    每帧 sample_pose → Skeleton3Dselfcheck
      gr2_bridge.{h,cpp}     libgr2 POD → Godot 类型;basis + 单位换算
      m2_material.{h,cpp}    Metin2 风格 ShaderMaterialmix / add
      dxt.{h,cpp}            DDS DXT1/3/5 软解
  assets/                     Metin2 资产(.gr2/.dds/locale/OutdoorA1/…,gitignored;换位置设 MT_ASSETS
  bgm/                        背景音乐(assets/ 同级,gitignored
  project/                    Godot 4.7 工程
    client_main.tscn/.gd      完整客户端入口(main_scene)→ AppFlow 登录串场
    app_flow.gd               LOGIN → SELECT → GAME 状态机
    main.tscn / main.gd       旧模型查看器 harness
    asset_root.gd             AssetRoot:资源目录解析(MT_ASSETS / res://../assets / .app 内外)
  docs/
    GODOT-POC-PLAN.md        开发计划(M0'M4 + 风险 + 验收)
    MIDREVIEW.md             Phase 1 中期评审
    BACKLOG.md               离可用客户端的分层未完成清单
    reference/               ← xrender-poc 的格式逆向笔记(archived
  test/
    golden/                  Godot 对拍截图
    bgfx-reference/          bgfx demo 参考截图 + 数值基线
    *.json                   noise_floor / m2-numeric / stress

授权

libgr2 全自研,不含 Granny SDK 代码 —— 例外:libgr2/src/oodle1.c 是泄露 SDK 的解码路径端口 (见 libgr2/README.md,仅限内部研究 / 非发布,对外发布前必须 clean-room 重写)。 本仓库内部研究用途,不对外公开。

S
Description
No description provided
Readme
1.5 GiB
Languages
GDScript 33.3%
Python 25.8%
C++ 25.4%
CartoCSS 10%
Shell 1.7%
Other 3.8%