feat(web): add texture paint with persistent packed images
Some checks failed
M6 deployable RC / quick (push) Has been cancelled
M6 deployable RC / chromium (push) Has been cancelled
M6 deployable RC / release (push) Has been cancelled

- Add TexturePaintView with brush, stroke, undo/redo and OPFS persistence.
- Import/pack local images with a valid ImageTile and replace stale packed files.
- Sync the engine packed asset cache after Main refresh and pack operations.
- Add pixel-level texture paint E2E for draw/undo and OPFS reopen.
- Document linked-image limits and the local RE-derived practice texture.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
mes123456
2026-11-13 05:02:21 +08:00
parent 7267db7cb4
commit d959f66839
14 changed files with 420 additions and 18 deletions

View File

@@ -45,21 +45,42 @@
- `AGENTS.md` 移植铁律已加入“OPFS 优先”条目。
### 4. Texture Paint 最小 2D 画笔
- 新 `web/app/src/app/TexturePaintView.tsx`:读取 packed Base Color 图像,画笔绘制/擦除、颜色/大小/强度、
指针笔画、撤销/重做、`data-last-action`、`packImage` 一次提交;挂载在 Texture Paint 工作区的图像编辑器。
- 本地练习图 `web/app/public/tutorial/texture-paint/re-texture-base.png` 从 RE 派生库
`black_tiles_wall_Base_Color.jpg` 提取(1024×1024),课程中导入为本地图像并设为材质 Base Color。
- 原生修复(web 缓存,不是桌面行为差异):
- `web_engine_blend_main_import_image` 用 `BKE_image_get_tile(image,0)` 建 tile 后再 pack,
修复新建图像 0×0、未打包。
- `web_engine_blend_main_pack_image` 在 pack 前 `BKE_image_free_packedfiles`,避免追加旧 packed file;
返回新 PNG 字节。
- `refresh_scene_from_main` 把 reader 的 `packed_assets` 同步回 `engine.packed_assets`;
`packImage` 成功后再更新对应 imageId 的缓存。修复 `requestAsset` 读旧图、重开丢笔画。
- 历史/撤销仍保存前后 packed_assets,undo 恢复旧图。
- 验证:
`DISPLAY=:1 CHROME_PATH=/usr/bin/google-chrome GPU_MODE=hardware npx playwright test --config playwright.config.ts tests/e2e/web-texture-paint-canvas.spec.ts --workers=1`
→ **2/2 PASS(42.9s)**:
- 画布中心像素由原图变为红色(绘制)、撤销后恢复;
- OPFS 保存 → reload → 最近项目恢复 → 重开后中心像素仍为红色。
## 待实现(按计划顺序)
1. **Texture Paint 最小 2D 画笔**:图像选择、颜色/大小/强度、光标、笔画、`packImage` 一次提交、
undo/redo、OPFS 保存重开;无 WASM。桌面语义参考 `editors/sculpt_paint/mesh/paint_image*.cc`。
2. **Geometry Nodes 画布**:共享图状态、React Flow 画布、位置/rename/属性、结果面板;
1. **Geometry Nodes 画布**:共享图状态、React Flow 画布、位置/rename/属性、结果面板;
需要一次 WASM 重建(location/properties)。
3. **Spreadsheet 交互式只读表**:数据源/过滤/行列/列重排/CSV;原生属性值读取需 WASM。
4. **Compositor 节点画布**:协议+React Flow+执行/Viewer;原生 writer/reader 缺失,需要最大的一次
2. **Spreadsheet 交互式只读表**:数据源/过滤/行列/列重排/CSV;原生属性值读取需 WASM。
3. **Compositor 节点画布**:协议+React Flow+执行/Viewer;原生 writer/reader 缺失,需要最大的一次
WASM 工作。
5. 其余缺口:Area 编辑器选择/⋮、Camera Perspective、Preferences、Outliner、Graph Editor。
6. 15 模块课程、15 个短视频、OPFS 保存重开流程、增量发布到 `https://49.232.250.35:58014/`。
4. 其余缺口:Area 编辑器选择/⋮、Camera Perspective、Preferences、Outliner、Graph Editor。
5. 15 模块课程、15 个短视频、OPFS 保存重开流程、增量发布到 `https://49.232.250.35:58014/`。
## 已知限制 / 未验证
- 纹理绘制、Compositor 画布、GN 画布、Spreadsheet 尚未实现;课程/视频尚未开始。
- 纹理绘制只支持本地 packed 图像;库链接图像(直接分配的 RE 材质贴图)被原生
`packImage cannot modify linked library images` 拒绝。课程通过导入 RE 派生的本地 PNG 并设为
Base Color 来绘制;后续可加“Make Local”入口。
- Compositor 画布、GN 画布、Spreadsheet 尚未实现;课程/视频尚未开始。
- 本轮只验证 Chromium + RTX 4060;未验证其他浏览器。
- 既有保存下载型 spec 尚未迁移;在迁移完成前不要把这些旧 spec 的失败当作产品回归。
- 远端首次 wasm 加载 154–193 秒;课程录制只做本地,页面需提示首载时间。