Files
shenandshen 1ab68bd06e Merge branch 'main' of http://192.168.21.200:8418/4v5u09Z5a4Yuc/metin2-client
# Conflicts:
#	docs/RENDERING-REPAIR-PLAN.md
2026-09-08 16:25:54 +08:00

74 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 渲染回归入口
第一批用例针对 R1 场景装配与 R2 角色选择,2026-09-08 开始执行。未宣称 40250 像素一致或最终包通过。
在仓库根目录运行:
本地 macOS 修改 C++ 后先执行 `bash script/rendering_test.sh`:它构建并同步 Godot 实际加载的 debug 路径,重签名后运行 CPU 绕序回归与选角截图。仅构建 Release 不会更新本地 Godot 的 debug 扩展。可传 `--hair=1001`;截图与哈希报告在 `build/rendering/selection-<timestamp>-<pid>/``--job=0..7``--main-part=0` 可复现无装备的八种族选择矩阵;`MTGODOT_GPUSKIN=1` 验证 GPU 路径。`--no-hair``--solid-body` 仅用于隔离诊断,其画面不能当作普通角色验收。
```bash
godot --headless --path project --script main_character_sync_test.gd
godot --headless --path project --script gamescene_test.gd
godot --path project --script gamescene_visual_test.gd
godot --path project --script gamescene_visual_test.gd -- --c1
```
- `main_character_sync_test.gd` 使用可控模型工厂,覆盖晚到实体/缺 race、网络重入、重复事件、移动不被回滚、失败节流与重试上限、VID 变化导致旧构建失效。通过标志是 `failures=0`,不能只看 Godot 退出码。
- `gamescene_test.gd` 使用不存在的地图,预期有加载错误日志;它只验证无地图装配,不能当作画面正常证据。
- `gamescene_visual_test.gd` 使用真实资产和实际 GameScene,通过 FakeClient 延迟提供 race=0 主角数据,**不发**主角信号。无账号和服务器写入。
- 默认先加载 A1`--c1` 随后提供 C1 服务器位置,用来验证晚到坐标能纠正地图选择。
- `gamescene_visual_test.gd` 除位置/地图/表面数外还断言 `feet_gap`:把动画冻结在 0.5 s
后取全部 MeshInstance3D 世界包围盒的最低点,减去该处地形高度,要求 |gap| ≤ 0.03 m
(R2-01 悬空修复的数值守卫;A1 与 C1 实测均为 0.001373 m)。报告里同时记录
`feet_y` / `feet_gap` / `feet_gap_max`
- 视觉用例输出 `build/rendering/gamescene-<timestamp>/game.png``report.json`。可用环境变量 `MT_RENDER_OUTPUT` 指定独立目录;复用路径会覆盖同名报告,建议每次新目录。
- 报告包含位置、相机、地图加载计数、模型表面数、引擎、关键脚本/扩展/模型路径哈希。资产依赖尚未穷举;这只是 R0 部分基线。
- 截图尺寸为 1280×720,角色待机固定在 0.5 秒。地形/环境动态因素尚未完全冻结,因此暂不设置像素误差硬阈值。
- 测试不配置学习技能,截图中的空快捷槽不代表技能图标验证成功。
## 不启动游戏的模型渲染回归(model_render_test.gd
```bash
godot --path project --script model_render_test.gd # 八职业,判定
godot --path project --script model_render_test.gd -- --race 0
godot --path project --script model_render_test.gd -- --bless # 重建基线
```
无地图、无网络、无服务器:直接用 `ui/player_view.gd` 离线装配一个角色,`wait`
动画冻结在 0.5 s,固定灯光(平行光 `(-42,155,0)` energy 1.1 + 环境色
`(0.6,0.62,0.68)` energy 0.8)、洋红背景、512×512。与 `char_bench_test.gd` 的区别
是它对像素算指标并断言,退出码即结论;bench 仍然只产图供人看。
指标(每个 race)与判定方式:
| 指标 | 含义 | 判定 |
| --- | --- | --- |
| `feet_gap_m` | 最低蒙皮顶点到 y=0 | 绝对,\|gap\| ≤ 0.03 m(实测 0.0007…0.0030 |
| `silhouette_px` | 正面剪影像素数 | 绝对 ≥ 3000;且对基线 ±3% |
| `head_cover` | 近景机位下发型盖住头部像素的比例(只统计 no_hair 里属于人体的像素) | 对基线 ±0.03 |
| `hair_mean_lum` | 只画发型时发型像素平均亮度 | 对基线 ±0.006 |
| `hair_mean_lum_ctrl` | 同上,但换回 R2-02 修复前的 `StandardMaterial3D(roughness=1)` | 负对照:必须比生产值高 ≥ 0.008 |
| `hair_lum_p99` / `hair_bright_frac` | 亮度 99 分位 / 超过 0.20 的像素占比 | 仅记录,不判定 |
为什么用平均亮度而不是「有多少像素炸白」:发色本身差别极大(武士近黑
`mean 0.061`,修罗银白 `mean 0.260`),任何跨职业的绝对亮度上限都不成立。平均
亮度对「整片发型被额外高光抬亮」敏感,基准差异由按职业记录的基线吸收。
负对照不是摆设:它每次都真的用旧材质再渲一遍,保证这条指标现在仍分得开好坏
(例如有人把灯光调暗到两边都测不出高光时会直接失败)。八职业实测旧材质相对
新材质的抬升是 +0.0109 … +0.0371,最小值 0.0109 给阈值 0.006/0.008 留了余量。
已验证它确实能抓到目标缺陷:把 `Metin2Model::_load_hair()` 临时改回
`StandardMaterial3D(roughness=1)` 重新编译后,**八个职业全部失败**
`hair_mean_lum` 偏离基线 0.0109…0.0371);改回 `mtgodot::make_material`
`PASS`
基线在 `test/rendering/model_baseline.json`,含引擎版本。改模型、改发型材质或改
这套灯光都会让基线失效,需要人工看过渲染结果再 `--bless`,并在
`docs/RENDERING-REPAIR-PLAN.md` 的执行记录里写清重建原因。
覆盖边界:只有离线单角色装配。不含地图、地形接触、真实光照昼夜、装备叠加、
40250 像素比对,也不能替代 `gamescene_visual_test.gd` 与导出包验收。
已知后续:脸部/脚底近景和区域差异器、完整资产哈希、四职业 GR2/GLB 对照、技能状态与图标用例、真实联机及普通 macOS `.app` 验收。