# RE 5000PBR × 猴头 GLB:渲染全面测试、HTML 教案与中文配音视频
日期:2026-11-12
状态:**功能实现完成;聚焦验证通过;整体产品验收仍由用户执行**
(`IMPLEMENTED_NOT_USER_ACCEPTED`)
## 本轮目标与范围
用户要求:在 Web Blender 中使用 `/home/mes123456/workinf_Blender_Wasm/re/5000PBR精简版`
的资产,对 `/home/mes123456/workinf_Blender_Wasm/re/猴头.glb` 做渲染功能全面测试;把操作过程截屏写成
初学者 HTML 教案;制作完整中文配音视频;发现的缺口按桌面 Blender 源码修 Web 移植,UI 缺口用 React;
需要时本地重编 WASM;全部使用绝对路径。
用户确认的范围:
- **只修实测阻塞**,不新增标准渲染设置 UI(宽高比、采样、透明背景、HDRI)。
- **只测 WebGL2 PBR**,不纳入本地原生 EEVEE/WASM(F12)或服务端 Blender。
前序批次已交付 RE 5000PBR 派生库、HTML 教案、20 张成片和 15 张操作截图;本轮补齐缺失的视频链路,
并修复实测暴露的一个真实导入缺口。
## 交付物
### 1. 中文配音视频(本轮新增)
| 项目 | 路径 / 值 |
| --- | --- |
| MP4 | `/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/lesson/video/re-pbr-lesson-720p.mp4` |
| 字幕 | `/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/lesson/video/re-pbr-lesson.zh-Hans.vtt` |
| 封面 | `/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/lesson/video/poster.jpg` |
| 时长 | 667.04 s(11:07),13 章 |
| 编码 | H.264 / AAC,1280×720,faststart |
| MP4 SHA-256 | `6a5b3b51c52945d0594a984ad6b5ff2e557ec319c574679673bd8d6d2a8a2916` |
| 旁白混音 SHA-256 | `adc2658938ad48b278aa434cb9635343491f7241f4632b4af6c9baa9271b9220` |
| VTT SHA-256 | `4199af3a9c1ad501ebd7832e43693d43d2bbd30a646a8285343eefc08a237aa3` |
| 封面 SHA-256 | `6461410e032de2c92f3f898873d9dca9834f2538e65cd0e4b2d8f3c443d0f444` |
| 旁白 | `zh-CN-XiaoxiaoNeural`,13 章,13 条 VTT cues |
| 章节截图 | `/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/lesson/video-steps/*.jpg`(13 张,1600×900) |
| 录制证据 | `/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-VIDEO-001/{screencast.webm,timeline.json,record-report.json,narration/,diagnostics/}` |
视频由有头 Chromium(`DISPLAY=:1`)真实操作录制,GPU 探测为
`ANGLE (NVIDIA Corporation, NVIDIA GeForce RTX 4060 Laptop GPU/PCIe/SSE2, OpenGL 4.5.0)`。
章节:开场、载入摄影棚、导入猴头 GLB、认识 Shading/RE 资产库、分配六种材质、设置渲染、
渲染与下载 PNG、保存与重开、诊断视图与教学曝光、位移与细分、对比视角、高清 2048 贴图、总结。
### 2. HTML 初学者教案
`/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/render-lesson.html`
+ `render-lesson.css`。13 节,75 个同源引用,**0 个断链**;包含真实操作截图、六种材质逐课、
20 张成片矩阵、黑图排查表和限制说明。视频、字幕、封面已嵌入。
### 3. 全面渲染测试证据(当前 wasm 重跑)
| 项目 | 路径 / 值 |
| --- | --- |
| 20 张成片 | `/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-RENDER-001/renders/*.png` |
| 采集报告 | `/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-RENDER-001/report.json` |
| 报告结果 | `status=PASS`、20 renders、15 steps、0 errors、20 个唯一 SHA |
| GPU | `ANGLE (NVIDIA Corporation, NVIDIA GeForce RTX 4060 Laptop GPU/PCIe/SSE2, OpenGL 4.5.0)` |
| GLB SHA-256 | `60267d607b63ceb5bfc972342a9ff17310d6978ff632f240ecb963c4d5a7e003`(`re/猴头.glb`) |
| 纹理状态 | 基线 `ready:1:0:`;六材质 `ready:5:0:`;重开 `ready:5:0:` |
| 材质编译 | 六个 RE 材质均 `COMPILED` |
| 当前 wasm | `/home/mes123456/workinf_Blender_Wasm/web/app/public/vendor/blender/web_engine.wasm` SHA-256 `31550b374cc0127c9b5468cebe65be37b8558c1604a28e99ec73a34be96c13f3` |
矩阵:基线 1024;6 材质 ×(1024 场景 + 1024 视口 + 512 场景);保存/重开后复渲染。
进阶证据沿用 `/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-LIMITS-001/`:
位移 1×/100×(968 → 61,952 三角形,mean delta 0.087)、诊断视图 3 张、+2 EV、对比视角、
HQ 2048(10.8 MB 库,67,633,152 bytes 解码);`check-re-pbr-limits.mjs` 本轮 PASS。
## 本轮修复的真实缺口
### 非 ASCII 文件名 GLB 导入失败(P0,已修复)
- **现象**:用真实文件入口打开 `/home/mes123456/workinf_Blender_Wasm/re/猴头.glb` 时,对象数保持 6,
控制台报 `RuntimeError: Error: Please select a file`;ASCII 夹具 `monkey-head.glb` 正常。
- **根因**:`/home/mes123456/workinf_Blender_Wasm/blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp`
的 `web_engine_blend_main_obj_io()` 原先把浏览器传来的原始文件名直接作为 Emscripten 虚拟文件系统的暂存名。
`猴头.glb` 的 UTF-8 文件名在 WASM 侧的 VFS 路径解析中不可用,glTF 导入器拿到不可解析路径后报
“Please select a file”。
- **修复**:暂存到磁盘的文件名把非 ASCII 字节替换为 `_`(例如 `______.glb`),扩展名与 ASCII 文件名保持不变;
UI 仍显示浏览器提供的原始文件名。桌面 Blender 本身支持 UTF-8 路径,本修复只影响 Web 的 WASM 暂存层。
- **构建**:`cmake --build /home/mes123456/workinf_Blender_Wasm/build_web_blender6 --target web_engine -j8`
→ `node /home/mes123456/workinf_Blender_Wasm/tools/web/sync-web-engine-runtime.mjs`;
新 wasm SHA-256 见上表。
- **验证**:视频“导入猴头 GLB”章节真实导入成功,状态栏 `Engine: GLB imported r2 (7 objects)`,
活动对象 Suzanne;20 张采集报告 `glbSha256` 与 `re/猴头.glb` 一致。
### 视频录制脚本阻塞(工具链,已修复)
- `tools/web/record-re-pbr-lesson-video.mjs` 原先的 `openStudio()` 依赖面板按钮路径,失败时不会回退;
失败前不保存视频/时间线。本轮增加:`--out` 生效、只清理 `screencast.webm`、保留原始 webm、
服务器退出检测、面板不可用时回退到 `[data-testid="blend-file-input"]`、保存对话框处理、
每章失败截图与部分时间线保留、失败时仍保存视频、硬件 GPU 回退即失败、时长 7–12 分钟守卫。
- 验证:13 章完整录制 `status=PASS`、0 errors、667.04 s。
### E2E 文案漂移(测试修正,非产品缺口)
- `web/tests/e2e/re-pbr-render-workflow.spec.ts` 仍按旧文案“打开图文教案”查找链接;面板现为
“打开图文/视频教案”。已改为正则 `/打开图文/`,主流程用例重跑通过(3.6 分钟)。
## 生产部署(2026-11-12)
| 项目 | 值 |
| --- | --- |
| 公网地址 | `https://49.232.250.35:58014/`(Let's Encrypt 证书,`curl` 校验 `ssl_verify_result=0`) |
| 入口 | nginx 58014 → `upstream blender_web_58014_backend 127.0.0.1:58114` |
| 服务 | `blender-web-58014.service`,www-data 运行 `deployment-http-server.mjs current/app` |
| 新 release | `/var/www/blender-web/releases/20261112-re-pbr-d5dd647`(`current` 指向) |
| 回滚 release | `/var/www/blender-web/releases/731af06aee6a2d2b61b902db9fd4b7bd5b04474e4689c48baf213fd5fcb3769f` |
| 部署工具 | `current/tools/web/deployment-http-server.mjs` + 8 个本地依赖模块(闭包 9 个),`current/docs/web/deployment-contract.json` |
| 静态产物 | `web/dist`(599MB;`assets/web_engine-*.wasm` 在服务器以符号链接指向 `vendor/blender/web_engine.wasm`,避免重复占盘) |
| wasm 传输 | nginx 58014 server 块启用 gzip(`application/wasm`);实测 241,949,523 → 79,395,379 bytes |
| 首次初始化 | 154–193 秒(两次实测;gzip wasm 单次下载;`init` 超时已从 30 秒提高到 300 秒) |
| 部署证据 | `/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-RENDER-001/deployed-app.png` |
部署期间修复的发布问题:
1. `web/app/public/engine-manifest.json` 的 single wasm SHA-256 仍是旧值 `551a86…`;主线程 `verifyWasmResource`
会额外下载 241MB 并失败。已改为实际 `31550b…`,并把校验 fetch 改为 `force-cache`。
2. 主线程重复校验与 worker 加载各下载一次 241MB;远程首次加载必然超过 30 秒 `init` 超时。
已移除主线程 wasm 字节重复下载(worker 的 `WasmModuleLoader` 仍做 SHA-256 校验),
`init` 超时改为 300 秒。
3. 241MB wasm 直接传输在服务器上行带宽下超过 300 秒;已在 nginx 58014 server 块启用 gzip
(仅 `application/wasm` 等文本类型,视频不压缩),压缩后 79.4MB。
4. 慢速首载时,启动自动新建 General 工程的模板下载会在用户打开 studio 之后应用,覆盖用户场景
(实测 studio 已 6 对象,几秒后又回到 General 3 对象)。已在文件选择/教案载入时设置
`startupTemplateCancelled`,并在 `newProject(true)` 的模板下载后再次检查;用户打开优先于启动模板。
## 验证结果
| 检查 | 结果 |
| --- | --- |
| `node tools/web/check-re-pbr-library.mjs` | PASS(6 材质、6 预览、3,707,202 bytes) |
| `node tools/web/check-re-pbr-library.mjs --hq` | PASS(6 材质、10,846,909 bytes、2048) |
| `node tools/web/check-re-pbr-lesson.mjs` | PASS(20 renders、15 steps、6 材质、0 断链) |
| `node tools/web/check-re-pbr-limits.mjs` | PASS(位移/诊断/HQ/GPU/重开) |
| `node tools/web/check-re-pbr-video.mjs` | PASS(13 章、13 cues、667.04 s、1280×720、faststart) |
| 有头 E2E `re-pbr-render-workflow.spec.ts` | **5/5 通过**(6.8 分钟;主流程 6.3 分钟,截断 GLB 负例、HEIGHT 位移、HQ 按需加载、HQ 2048 尺寸均通过) |
| 20 张采集 | PASS(20/20、unique SHA 20、0 errors、RTX 4060) |
| 教案引用 | 75/75 存在,0 断链,无远程 URL |
| 教案页面冒烟(Chromium,dev) | 56 张图片全部解码、视频 `duration=667.04`/`readyState=4`、VTT 200 + 13 cues、无 4xx |
| 生产构建 | `npm run build` PASS(typecheck + vite build;`web/dist` 含视频、字幕、poster、13 张章节截图、新 wasm) |
| 教案页面冒烟(生产 dist + 部署服务) | 56 张图片全部解码、视频 667.04 s、VTT 13 cues、无 4xx |
| 视频音频 | AAC 单声道 48 kHz;`volumedetect` mean −23.4 dB、max −2.6 dB(非静音) |
| 线上首次加载 | `init` 192.8 s(范围 154–193 s);wasm 仅 1 次 200(`Content-Encoding: gzip`,79.4MB);无 pageerror/console error |
| 线上启动竞态 | init 完成后**立即**打开 studio,6 对象保持 10 秒以上不被启动 General 覆盖;8 秒内进入 `Engine: SceneIR r1 (6 objects)` |
| 线上场景流程 | studio 6 对象 → `猴头.glb` 7 对象(`Engine: GLB imported r2`,Suzanne 1225 顶点/969 面) |
| 线上 PBR 渲染 | 512×512,`data-texture-status=ready:1:0:`,产物写入 OPFS(截图见 `deployed-app.png`) |
| 线上教案 | 56 张图片全部解码、视频 `duration=667.04`、VTT 200 + 13 cues、0 个 4xx |
## 未验证 / 限制
- Web 渲染是 three.js WebGL2 PBR(`physical-v1`),不是 EEVEE/Cycles 路径追踪;玻璃/金属/折射/GI
与桌面物理精度不同。本机原生 EEVEE/WASM(F12)与服务端 Blender 未验证。
- 六种 RE 材质都是深色砖石/防滑表面,整体偏暗是材质本身;用诊断视图和教学曝光判断,而不是只看亮度。
- 标准渲染设置 UI(非方形宽高比、采样/抗锯齿、透明胶片、HDRI/世界环境编辑)未在本轮补齐;
用户选择“只修实测阻塞”,这些记录为已知限制。
- HQ 2048 为按需加载;mipmap 可能使实际显存比 base-level 预算高约 1/3。
- 按仓库策略只验证 Chromium;Firefox/WebKit、移动端未运行。
- 视频旁白按 13 章覆盖操作步骤;材质原生追加、PBR 渲染、HQ 加载的等待段保留真实耗时,
部分章节为静默操作画面(未做变速剪辑),这是为了不伪造操作时延。
- 未做用户实际使用验收;本轮的检查器/E2E/录制 PASS 不等于整体产品验收。
## 证据路径
- 视频:`/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/lesson/video/`
- 视频章节截图:`/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/lesson/video-steps/`
- 教案:`/home/mes123456/workinf_Blender_Wasm/web/app/public/tutorial/pbr/render-lesson.html`
- 20 张成片与报告:`/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-RENDER-001/`
- 视频录制/混音证据:`/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-VIDEO-001/`
- 进阶限制证据:`/home/mes123456/workinf_Blender_Wasm/tests/golden/RE-PBR-LIMITS-001/`
- 本轮源码修复:`/home/mes123456/workinf_Blender_Wasm/blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp`
- 录制脚本:`/home/mes123456/workinf_Blender_Wasm/tools/web/record-re-pbr-lesson-video.mjs`