# 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 反证清单 + 一页纸结论的"正式移植还缺什么"部分