shenleiandClaude Opus 5.5 ac4c2aa4e0 2V2-e.3: live smoke of the Godot render adapter
Fix the material cache key: bools given to %d failed to format, so every
draw shared the first material (the face texture). The render test now
checks one texture per texture name. Offline and live (192.168.21.203)
show the dressed main character; live also shows the nearby mobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 20:42:24 +09:00
2026-08-31 20:04:32 +09: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)停止开发,其可复用部分—— libgr2(gr2 v6/v7 读取器,已对拍 Granny)、formats(.msa/.msm)、oracle(Granny 真值工具)、 tools(libgr2 校验工具)、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)· iOS(iPhone 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 — 静态渲染。gr2 → Skeleton3D + ArrayMesh + Skin + 材质。 warrior_cheongrin(75 骨 / 5 表面 / 3324 顶点)正立、朝 +Z、贴图正确 (test/golden/m1-bindpose.png)。多骨架:warrior_lord(v6,74)、assassin(v6,95,17 表面)、 shaman_lord(v7,93) 均正确加载渲染。
  • M2 — 骨骼动画。Metin2AnimPlayer _process 里 gr2::sample_pose(跨文件) → 默认 CPU 线性混合蒙皮(把 libgr2 的 Σ w·invWorld·world 直接作用到顶点,每帧重建 mesh)。 get_bone_global_pose vs conv(world) 全骨 ≤2.6e-5;selfcheck 0 NaN;dance_1 等所有动作 头/护甲/躯干正确,与 xrender-poc bgfx demo 一致。 MTGODOT_GPUSKIN=1 走自写蒙皮顶点着色器(m2_material SRC_SKIN:逐骨完整 4×3 矩阵 存 RGBAF 纹理,绕过 Skeleton3D —— Godot 内置 GPU 蒙皮会正交化、丢 Granny 烘在 rig 骨上的 shear,warrior 7 根 / sura 16 根,见 test/shear-bones-survey.md)。人群场景用它。 .msa:anim_path 收 .msa → motion .gr2 + Accumulation + MotionEventData (get_events() / motion_event 信号,带循环回绕)+ LoopData 元数据;播放器 loop=false 可播一次并发 playback_finished(片段循环次数执行仍在 backlog C4)。 .msm:gr2_path 收 .msm → 自动加载 BaseModelFileName(含散包目录扫描)+ get_hair_options() 发型目录(发型 mesh 挂接留 Phase 2)。
  • M2.5 — 材质与观感保真。ShaderMaterial(modulate 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 2。compare.py 已有进程/截图/结构硬门禁,像素差仍为 advisory;收尾重点是前台/真机性能重测与桥接层全语料 draw 冒烟(默认已是 CPU LBS)。

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


环境

组件 版本 / 位置 说明
Godot 4.7.1(/opt/homebrew/bin/godot,Homebrew 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-poc,2026-08-29)

目录 内容 谁用
libgr2/ gr2 v6/v7 只读读取器(header/section/Oodle1/类型树/骨架/网格/曲线/材质)。零第三方依赖。9166 语料 fuzz 0 崩溃;bind pose + 蒙皮对拍 Granny 2.9.12 ≤6.5e-5。含 dump_materials()。 extension(xrender::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_diff(libgr2 vs oracle 逐字段对拍)/ anim_probe(每骨 world 3×3 的 det/shear/scale 探针,查蒙皮走样)。 libgr2 回归
docs/reference/ xrender-poc 的格式逆向笔记(M0–M4 施工文档 + 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); extension 只 target_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/                     ← vendored:gr2 读取器(xrender::libgr2)
  formats/                    ← vendored:msa/msm/textscript
  oracle/                     ← vendored:Granny 真值工具(exe/dll 不入库)
  tools/                      ← vendored:gr2dump / gr2fuzz / oracle_diff
  extension/
    CMakeLists.txt           mtgodot SHARED + godot-cpp(consume 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 → Skeleton3D;selfcheck
      gr2_bridge.{h,cpp}     libgr2 POD → Godot 类型;basis + 单位换算
      m2_material.{h,cpp}    Metin2 风格 ShaderMaterial(mix / 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
2.6 GiB
Languages
Makefile 90.1%
C++ 7.6%
CMake 1.3%
Python 0.5%
POV-Ray SDL 0.2%