chore: checkpoint web Blender feature-gap work, docs and tests
- update native web_engine sources and rebuilt wasm artifacts - add task cards, status notes and tooling scripts - add web e2e specs, tutorial UI sources and tutorial assets - sync golden task manifests and audit records Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
89
docs/status/WEB_UI_PBR_20261111.md
Normal file
89
docs/status/WEB_UI_PBR_20261111.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# Web UI 对标 + PBR 真实案例实现状态(2026-11-11)
|
||||
|
||||
- 状态:`in_progress`(实现证据,不宣称验收)
|
||||
- 范围:Outliner React treeview、着色器编辑器 React Flow、真实 PBR 资产链路与色彩管理
|
||||
- 验收:`NOT_CLAIMED`
|
||||
|
||||
## 已实现
|
||||
|
||||
### Outliner
|
||||
|
||||
- 新增 `web/app/src/app/ui/OutlinerTreeView.tsx`、`outliner-tree-data.ts`、`outliner-tree.css`。
|
||||
- 使用 `react-accessible-treeview@2.11.2` 渲染原生 `tree.rows`;保留选择、展开、拖放 payload、重命名、Remap、可见性、截断提示。
|
||||
- `App.tsx` 原生行渲染改为 treeview `renderRow`,并保留 `role="treeitem"` 可访问名、`data-node-id`/`data-active`、`.tree-node-name`、展开按钮可访问名。
|
||||
- 修复 treeview 受控展开反馈环:不再由库自动触发 `OUTLINER_TOGGLE_EXPAND`,仅用户按钮/键盘触发。
|
||||
|
||||
### 着色器编辑器(React Flow)
|
||||
|
||||
- 新增 `web/app/src/app/ui/ShaderNodeCanvas.tsx`、`ShaderNode.tsx`、`shader-flow-adapter.ts`、`shader-node-catalog.ts`、`shader-node.css`。
|
||||
- `WasmShaderEditor.tsx` 画布主体切换到 `@xyflow/react@12.12.1`:
|
||||
- 节点拖动 → `MOVE`
|
||||
- 端口拖拽 → `LINK`,边删除 → `UNLINK`
|
||||
- 节点内 socket 编辑 → `SET_SOCKET`
|
||||
- Shift+A / 工具栏添加节点 → `ADD`
|
||||
- 节点属性(Mix data/blend、Mapping vector type、Normal Map space、Bump invert、UV Map 名称)→ `SET_PROPERTY`
|
||||
- Image Texture 换图 → `SET_IMAGE`
|
||||
- 只读链接材质、revision 冲突、未知节点占位、全部端口折叠。
|
||||
- 坐标约定 `position={x, -y}`;读回 `fromSocket/toSocket` 与命令 `fromSocketId/toSocketId` 由适配器唯一转换。
|
||||
- SSE/React Flow 要求:CSP 增加 `style-src-attr 'unsafe-inline'`,脚本/Worker 仍严格;去掉 attribution 隐藏。
|
||||
|
||||
### 原生读回与编辑
|
||||
|
||||
- `web_engine_blend_reader.cpp`:节点类型补齐 MIX/MAPPING/TEX_COORD/UV_MAP/BUMP/SEPARATE_COLOR/OBJECT_INFO;socket `available`/`hidden`;节点属性(dataType/blendType/vectorType/space/invert/projection/interpolation/extension/uvMap/mode);材质 `textureBindings`;`normalImageId` 真正赋值;Image `colorSpace` 读取(当前资产未返回,见残余)。
|
||||
- `web_engine_main_state.cpp`:`editShaderNode` 新增 `SET_PROPERTY`/`SET_IMAGE`,ADD 支持 UV_MAP/OBJECT_INFO/SEPARATE_COLOR;`setShaderGraph` 类型扩展并按 socket **identifier** 绑定(修复 Mix 同名 socket)。
|
||||
- 新增 `packImage`:外部 PNG/JPEG 字节直接打包进已有 Image,保留节点链接,允许 0 尺寸由调用方按文件头提供。
|
||||
- 新增 `assignMaterialSlot`:把已有材质装入对象槽(`BKE_object_material_slot_add` + `BKE_object_material_assign`),属性面板材质槽下拉已接入。
|
||||
- `web_engine_api.cpp`、`web/protocol/web-engine.ts`、`web-engine.worker.ts`、`web-engine-capabilities.ts` 同步命令。
|
||||
|
||||
### PBR 显示
|
||||
|
||||
- `three-adapter/pbr.ts`:按场景 `colorManagement.viewTransform` 选择 AgX/Standard/Neutral/ACES;`toneMappingExposure = 2 ** exposure`;`data-tone-mapping` 场景驱动。
|
||||
- `three-adapter/texture-assets.ts`:应用 `map`、`normalMap`+strength、`metalnessMap`、`roughnessMap`、`emissiveMap`、`alphaMap`、`bumpMap`;贴图驱动时中性化 factor。
|
||||
- `texture-assets.applyEnvironment` 使用 `WorldIR.environmentRotation`。
|
||||
- `render-assets.ts` 纹理用途扩展;`scene-ir.ts` 校验新节点类型/属性/textureBindings。
|
||||
- 外部贴图 UI:着色器编辑器“外部贴图”列表;文件先 `StorageClient.putAsset` 写入 OPFS,再 `packImage`;项目保存继续走 `StorageClient.saveProject`(OPFS)。
|
||||
|
||||
## Chromium 实测(手动探针,实现证据)
|
||||
|
||||
- `tests/files/web/m12_glb_main_v1/pbr.blend`:Outliner 树、React Flow 2 节点/1 连线;拖动、连线、断开、改 Roughness、添加 Mapping 均发出正确原生命令;保存后重开 Roughness=0.7、Mapping 位置/连线保留;Ctrl+Z / Ctrl+Shift+Z 恢复 0.28 / 0.7。
|
||||
- `blender-5.2.0/tests/files/io_tests/blend_geometry/materials_pbr.blend`:ImageTexture/Principled 读回;三张外部 PNG 经 OPFS→packImage 变为 PACKED;viewport 显示红/金属黑 PBR 立方体;`data-tone-mapping` 场景驱动。
|
||||
- `cubes_with_textures.blend`:读回 MAPPING/UV_MAP/SEPARATE_COLOR/IMAGE_TEXTURE;textureBindings 含 BASE_COLOR/ROUGHNESS/NORMAL/EMISSION,`normalImageId` 已赋值。
|
||||
- `user-testing/WEB_Blender_Robot_Tool_20260916/outputs/robot-project.blend`:18 对象、7 个 link 材质;着色器材质列表可见。
|
||||
|
||||
## Playwright 用例
|
||||
|
||||
- `web/tests/e2e/outliner-treeview-production.spec.ts`:通过。
|
||||
- `web/tests/e2e/shader-editor-flow-production.spec.ts`:通过(headless 合成指针的节点拖动不稳定,拖动由手动 Chromium 探针覆盖;其余连线/删除/添加/参数/保存重开在用例内)。
|
||||
- `web/tests/e2e/pbr-real-assets-production.spec.ts`:通过。三张外部 PNG 在 Web UI(`?ui=web`)下经 OPFS→`packImage` 打包,SceneIR 依次 r7/r10/r13,外部贴图列表清空。
|
||||
- 三条用例合并运行:`3 passed (37.3s)`。
|
||||
- 注意:测试使用 `?ui=web`(React UI 模式)以避免 headless SwiftShader 下原生 GPU 节点编辑器绘制抛 `WASM_INIT_FAILED`;这不是 React UI 路径的缺陷。
|
||||
|
||||
## 残余缺口
|
||||
|
||||
1. Image `colorSpace` 未从 `.blend` 读出(`undefined`);当前按纹理用途推断 sRGB/Non-Color,颜色贴图默认正确,非默认色彩空间未覆盖。
|
||||
2. `robot-project.blend` 保存工作区中 Outliner 深层的展开按钮发送选择而非 `OUTLINER_TOGGLE_EXPAND`;`pbr.blend`/`basic_scene.blend` 展开正常。需继续定位该工程的 workspace/area 映射。
|
||||
3. Headless Playwright 合成鼠标拖动 React Flow 节点不稳定;真实 Chromium 手动拖拽正常。
|
||||
4. Compositor 原生 `setCompositorNodeGraph` 仍未实现;Geometry Nodes 尚未复用 React Flow 画布。
|
||||
5. 非 Principled BSDF(Glass/Hair/Anisotropic 等)、Subsurface/Volume/UDIM/HDRI 仍按 capability block 或后续批次处理。
|
||||
6. 本轮未运行全量回归、未生成正式 candidate receipt;构建哈希与证据需在后续批次绑定。
|
||||
|
||||
## 构建与构件
|
||||
|
||||
- 原生:`cmake --build build_web_blender6 --target web_engine -- -j8`
|
||||
- 同步:`node tools/web/sync-web-engine-runtime.mjs`
|
||||
- 前端:`cd web && npm run build`
|
||||
- `web_engine.wasm` SHA-256:`84fc21e7728b580579424f97495d27275d30c01f2898ccadf4e368ea37d646ea`(与 `web/app/src/vendor/blender/web_engine.wasm` 一致)
|
||||
- `web/dist/index.html` SHA-256:`d36f002b7793b7684f3ac570537bd33527143a6ea64fb43b3dabff0d3d313a8e`
|
||||
|
||||
## CSP 与样式加载
|
||||
|
||||
- React Flow 需要内联 style 属性;部署 CSP 改为 `style-src 'self'; style-src-attr 'unsafe-inline'`,脚本/Worker 指令保持严格。
|
||||
- React Flow 与新增组件 CSS 通过 `web/app/index.html` 的同源 `<link>` 引入(`ui/xyflow.css`、`ui/outliner-tree.css`、`ui/shader-node.css`),避免 Vite dev 的内联 `<style>` 注入被 CSP 阻断;生产构建提取为 CSS 文件。
|
||||
- `tools/web/check-csp-policy.mjs` 已改为仅对脚本/Worker 指令拒绝 `'unsafe-inline'`,并断言 `style-src-attr` 的最小放宽。既有 `tests/golden/M13-05A/csp-report.json` 需在后续验收批次重新生成。
|
||||
|
||||
## OPFS 资产策略
|
||||
|
||||
- 渲染用 packed 图像:`cachePackedAssets` 在每次快照后通过 `StorageClient.putAsset` 写入 OPFS。
|
||||
- 外部贴图:用户选择文件后先 `putAsset`(OPFS),再 `packImage` 进工程;项目保存走 `StorageClient.saveProject`(OPFS)。
|
||||
- 打开工程时提供的库 `.blend` 文件在 `openBlend` 前写入项目 OPFS(`application/x-blender`)。
|
||||
- 资产库/OBJ/多分辨率/VDB 等既有导入路径继续使用 `putAsset`。
|
||||
Reference in New Issue
Block a user