Networked client on the existing Godot 4.7 + libgr2 renderer:
- net: m2dev wire protocol (libsodium KX + XChaCha20), auth/select/game
phases, EntityStore world model, ~all GC/CG headers. char create/delete,
private shop / mall / cube, SHOP_GC_START_EX, guild, party (+ CG_PARTY_SET_STATE),
quests, dragon soul, refine, safebox, exchange.
- UI: in-game windows migrated 1:1 from the reference uiscript/root .py —
char status (/stat), inventory+equipment, select-item ([SELECT_ITEM] quest
token), system-option + game-option + ESC system menu, private-shop 39-grid,
party info board, shop tabs, atlas, minimap, quickbar, chat, …
- EterGrnLib polish: GR2 material blend/two-sided, LOD crossfade, motion-event
dispatch, contact shadow, ray-AABB picking, weapon grip pre-transform.
Portable asset IO (A1) — all extension/libgr2/formats/mtproto reads routed
through godot::FileAccess (res:// PCK works on iOS/Android); standalone-lib
*_path() kept for the non-Godot CTests. AssetResolver + PropertyRegistry
switched to a baked index (bake_asset_index.gd) instead of std::filesystem.
Mobile builds: build-{android,ios}.sh, export-android.sh, pack-assets.sh,
gen-debug-keystore.sh. Assets ship as a zip mounted at runtime by
project/asset_pack.gd (adb push now; HTTP download is a drop-in later).
ctest 10/10, 34 GDScript suites, macOS/iOS/Android all build.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013EJxkHiNKS4kybHS3XKyAJ
93 lines
4.4 KiB
Markdown
93 lines
4.4 KiB
Markdown
# M4 · 逼近真实负载(可选)
|
||
|
||
> 总纲:[`../PLAN.md`](../PLAN.md) §06。
|
||
> 本文件是 M4 的详细施工文档。**可选** —— M3 全绿已经能给出 go/no-go 结论,M4 只是把结论从"骨骼网格能跑"推到"接近真实负载也能跑"。
|
||
|
||
---
|
||
|
||
## 目标
|
||
|
||
在 M3 已验证的基础上,加 GPU 蒙皮、eterpack 加载、多角色 + 地面 + 简单光照、LOD 切换,
|
||
把性能结论从简化场景推到接近真实的负载。
|
||
|
||
## 前置
|
||
|
||
- [M3](./M3-mobile.md) 全部门禁通过。
|
||
- [M2](./M2-anim-skinning.md) 的 CPU 蒙皮作为 GPU 蒙皮的对拍基准。
|
||
|
||
## 交付物
|
||
|
||
| 产物 | 位置 |
|
||
|---|---|
|
||
| GPU 蒙皮路径(`vs_pnt_skinned` 全量启用 + 骨骼矩阵 texture 上传) | `engine/skinning.cpp` `app/shaders/` |
|
||
| eterpack 加载路径接入 | `reuse/EterPack/` + `engine/scene.cpp` |
|
||
| 多角色场景(1 / 8 / 20 / 50) + 地面 + 方向光 | `app/` |
|
||
| CPU vs GPU 蒙皮对拍报告 | `test/m4-skin-cmp.json` |
|
||
| 扩展性能曲线 | `test/m4-perf-curve.json` |
|
||
|
||
---
|
||
|
||
## 任务分解
|
||
|
||
### T1 · GPU 蒙皮
|
||
|
||
- 骨骼矩阵改走 GPU:小骨架用 `bgfx::setUniform(u_bones, mtx, boneCount)`(uniform 数组,上限 ~128);大骨架 / 多实例用**骨骼矩阵 texture**(`bgfx::createTexture2D(RGBA32F)` 每帧 `updateTexture2D`,VS 里 `texelFetch`)。
|
||
- `vs_pnt_skinned.sc` 从 M2 的演示版转正。
|
||
- **完成判据(门禁)**:GPU 蒙皮输出顶点与 M2 的 CPU LBS 结果一致(离屏 transform feedback 或渲到 RT 读回对拍),`‖Δ‖ < ε_vtx`。
|
||
|
||
### T2 · eterpack 加载路径
|
||
|
||
- `reuse/EterPack`(冻结拷入):`CEterPackManager::RegisterPack` + `Get(mappedFile, "d:/ymir work/.../xxx.gr2", &data)` → LZO 解压 + 解密 → 裸字节喂 `libgr2`。
|
||
- 需要 `assets/` 打包成 `.eix/.epk`(`m2dev-client-main/assets/PackMaker.exe` 或 `pack.py`,Windows 侧一次性做)。
|
||
- **完成判据(门禁)**:同一 gr2 经 eterpack 路径 vs 散文件路径,`libgr2` 产出的骨架 / 网格 byte-identical。
|
||
|
||
### T3 · 多角色场景
|
||
|
||
- N 个 warrior 实例(各自动画时钟错开),一块带贴图的地面(用一个 zone 静态 gr2 或程序化 quad + terrain 贴图),一个方向光。
|
||
- 实例化:bgfx `instanceDataBuffer`(每实例 model 矩阵);蒙皮 texture 每实例一段。
|
||
- **完成判据**:50 个角色可交互帧率(真机上 ≥ 20fps 作为下限参考,非硬门禁)。
|
||
|
||
### T4 · LOD 切换(运行时)
|
||
|
||
- 按相机距离在 LOD 0–3 间切(用 M2 T6 已验的 LOD 一致性)。
|
||
- 切换要平滑:同帧不要让顶点跳(M2 已验位移 < 阈值),或加一帧 cross-fade。
|
||
- **完成判据**:镜头拉远/拉近,LOD 切换无肉眼可见 pop。
|
||
|
||
### T5 · 扩展性能曲线
|
||
|
||
- 简化 + 满配角色,各 1 / 8 / 20 / 50 个,三台基准机各跑一遍。
|
||
- 画帧时间 vs 角色数曲线,标出 CPU 蒙皮 vs GPU 蒙皮两条线。
|
||
- 写进 `test/m4-perf-curve.json`。
|
||
|
||
---
|
||
|
||
## 门禁(go / no-go)
|
||
|
||
- **GPU 蒙皮结果与 CPU 一致**(`‖Δ‖ < ε_vtx`)。
|
||
- **eterpack 路径与散文件结果一致**(byte-identical 骨架 / 网格)。
|
||
- 50 角色可交互帧率(参考线,非硬门禁)。
|
||
- LOD 运行时切换无 pop。
|
||
|
||
## 验证
|
||
|
||
- CPU / GPU 蒙皮对拍(T1)。
|
||
- eterpack vs 散文件对拍(T2)。
|
||
- 扩展性能曲线覆盖 1 / 8 / 20 / 50 角色 × 两种复杂度 × 三台机(T5)。
|
||
|
||
## 本步风险
|
||
|
||
| 风险 | 缓解 |
|
||
|---|---|
|
||
| GPU 蒙皮骨骼矩阵上传带宽(每帧每实例 60 骨 × 64B) | 用骨骼 texture + `texelFetch`,只 update 变化实例;half-float 视精度 |
|
||
| eterpack 解密 key / IV(客户端从服务器拿 `RetrieveHybridCryptPackKeys`) | demo 用离线打包的非加密 pack,或把 key 硬编进 `test/`(自用不公开)|
|
||
| 实例化 + 蒙皮 texture 在 GLES3 的上限 | GLES3 保证 `texelFetch` + `RGBA32F` sampled;Adreno 老驱动测一下 |
|
||
| 50 角色 draw call 爆 | 按材质 / 程序批;满配角色本来就多 draw call,接受较低帧率 |
|
||
|
||
## DoD 清单
|
||
|
||
- [ ] GPU 蒙皮输出 == CPU LBS(`test/m4-skin-cmp.json`)
|
||
- [ ] eterpack 路径 == 散文件路径(骨架 / 网格 byte-identical)
|
||
- [ ] 多角色场景(含地面 + 光)可跑,LOD 运行时切换无 pop
|
||
- [ ] `test/m4-perf-curve.json`:1/8/20/50 × 简化/满配 × 三机,CPU/GPU 两条线
|
||
- [ ] 结论并入 PLAN §10.1 反证清单 + 一页纸结论的"正式移植还缺什么"部分
|