diff --git a/docs/BLENDER_5_2_WEB_FEATURE_PARITY.md b/docs/BLENDER_5_2_WEB_FEATURE_PARITY.md index 08d55449..7e3dc72c 100644 --- a/docs/BLENDER_5_2_WEB_FEATURE_PARITY.md +++ b/docs/BLENDER_5_2_WEB_FEATURE_PARITY.md @@ -213,10 +213,10 @@ operator search;这不等价于 Blender 全量 operator registry、context men 4. `.blend`/image/media/script fuzz、OPFS quota、OOM、设备丢失、网络中断和恢复验证。 5. 许可证/source offer/SBOM、确定性包、文档状态与测试报告一致后才能发布。 -当前证据为 13 条有效记录、15 个缺失,整体仍为 `BLOCKED`;新增 VDB 边界记录只证明 -转换/manifest/range 协议与显式阻断;已通过 1M geometry、 +当前证据为 13 条有效记录、15 个缺失,整体仍为 `BLOCKED`;VDB 专项记录已证明真实 +desktop/server converter、HTTP/OPFS、Float32 WebGPU 双生产视口与 Main 属性重开当前切片;已通过 1M geometry、 600 帧 OPFS simulation cache、4K/8K texture、运行中断网和主线程 WebGL device loss, -仍缺 10M geometry、长媒体、OOM 及 N-016 至 N-025 上游 family 的完整验收。 +仍缺 10M geometry、长媒体、OOM 及 N-015 至 N-025 上游 family 的完整验收。 ## 默认验收入口 @@ -231,5 +231,6 @@ npm --prefix web run lint npm --prefix web test npm --prefix web run test:authoring-roundtrip npm --prefix web run test:capability-gates +npm --prefix web run test:status-consistency npm --prefix web run test:e2e ``` diff --git a/docs/PROJECT_STATUS_AND_NEXT_WORK.md b/docs/PROJECT_STATUS_AND_NEXT_WORK.md index 345ba44b..bb55db09 100644 --- a/docs/PROJECT_STATUS_AND_NEXT_WORK.md +++ b/docs/PROJECT_STATUS_AND_NEXT_WORK.md @@ -40,7 +40,7 @@ SQLite WASM 和 Bitbybit/OCCT 均不在当前依赖范围内。Three.js、WASM | 发布性能/故障门 | Chromium 118 条 E2E、1M geometry、600 帧 OPFS cache、4K/8K texture、运行中断网、主线程 WebGL context loss | 已完成已声明门;10M、长媒体、OOM 和 Offscreen device loss 仍缺 | | Shader Main | RGB/Value/Principled/Image Texture/Normal Map/Output 整图事务、资源门和保存重开 | 已完成六节点写回子集;任意图/编译仍阻断 | | NLA Main | 单对象 Action Clip 整栈写回、SceneIR 重开和 native frame 求值 | 已完成有限 Action Clip 子集 | -| 非 Mesh 数据块 | Curve/Surface/Font/Metaball Main 权威写回与保存重开、真实 evaluated mesh、PointCloud/Curves/Hair 属性、WNM chunks、双 viewport、handle-local 连续 preview/单次 Main commit、desktop golden 与 7 对象 GLB/USD round-trip | N-015 整体 BLOCKED;VDB 资源 catalog、desktop OpenVDB->NanoVDB 与分块协议已完成,server/WebGPU/保存重开/golden 未完成 | +| 非 Mesh 数据块 | Curve/Surface/Font/Metaball Main 权威写回与保存重开、真实 evaluated mesh、PointCloud/Curves/Hair 属性、WNM chunks、双 viewport、handle-local 连续 preview/单次 Main commit、desktop golden 与 7 对象 GLB/USD round-trip | N-015 整体 BLOCKED;VDB 的 desktop/server converter、HTTP/OPFS、Float32 WebGPU 双生产视口和 Main 属性重开已完成,GPU demand paging、联合重开、完整材质、大 bundle/OOM 和发布 golden 未完成 | ## 3. 部分完成或仍有边界的能力 @@ -53,7 +53,7 @@ SQLite WASM 和 Bitbybit/OCCT 均不在当前依赖范围内。Three.js、WASM | `.blend` 保存 | 场景状态、modifier、Mesh Edit、材质/UV、动画/约束和对象层级命令均写 Main;历史、原子保存、快照和日志重放可恢复 | skin/shape-key decimate 保持结构化阻断 | | Blender UI 对标 | 默认区域、当前 Mesh Edit、raycast、多选、拖拽 gizmo、层级/材质/动画面板和核心快捷键已闭环 | Sculpt、Geometry Nodes 编辑器等未声明能力继续结构化阻断 | | 未声明能力扩展 | 四项协议/安全门均已细分;Sculpt 属性/有界 Main stroke、Simulation cache、六节点 Shader Main 和 Action Clip NLA Main 已有正例 | PBVH、GN lazy-function/Simulation 求值、其余 Shader Node、Web compiler、完整 NLA/UI/GLB 图映射仍 planned/结构化阻断 | -| 非 Mesh 数据块 | 1M 点 reader budget、ID_MB/PT/VO/VF 注册、Main control-point/topology/body/element/Font style link commands、一维多 spline 与批量 handle/cyclic、二维 Surface topology transaction、undo/save/reopen、真实 evaluated mesh、WNM SHA chunks、handle raycast/handle-local 连续 preview/单次 commit、7 对象 GLB/USD、Chromium quota、VDB/NanoVDB 协议与 desktop converter | 新外部字体导入及 VDB server job、WebGPU renderer、材质、保存重开和 golden 仍 planned/阻断 | +| 非 Mesh 数据块 | 1M 点 reader budget、ID_MB/PT/VO/VF 注册、Main control-point/topology/body/element/Font style link commands、一维多 spline 与批量 handle/cyclic、二维 Surface topology transaction、undo/save/reopen、真实 evaluated mesh、WNM SHA chunks、handle raycast/handle-local 连续 preview/单次 commit、7 对象 GLB/USD、Chromium quota、VDB desktop/server converter、HTTP/OPFS 和有界 WebGPU 双视口 | 新外部字体导入,以及 VDB demand paging、完整材质、联合保存重开、大 bundle/OOM 和发布 golden 仍 planned/阻断 | | 大场景 | Worker 二进制解码、per-mesh/range transferable、linked Mesh 实例化、LOD/OPFS cache、frustum culling、能力门 OffscreenCanvas Worker、100k/1M 内存门 | 超出当前 WBG1 的网络式渐进流送仍属于后续性能扩展 | | Decimate 全对标 | Collapse 的当前网格集合已覆盖,错误路径结构化 | Un-Subdivide、Dissolve、所有 delimiter/权重/对称组合及大模型性能矩阵未完成 | @@ -184,8 +184,9 @@ save/reopen、真实 legacy evaluated mesh、PointCloud/Curves 属性和 WNM 二 主线程与 OffscreenCanvas 消费同一 chunks;GLB 只接受真实 evaluated mesh,USD 提供 `UsdGeomMesh`、`UsdGeomPoints` 和 `UsdGeomBasisCurves` 的机器可读映射/损失。 VDB 已改为 desktop/server OpenVDB -> NanoVDB、浏览器分块读取 + WebGPU。真实资源 catalog、 -desktop converter 和协议/range 基础件已接通,但 server job、renderer、材质、保存重开和 golden 仍阻断;handle-local 专用 gizmo -已接通,新字体导入等剩余项按 `docs/status/N-015.md` 和 +desktop/server converter、HTTP 断点续传、OPFS 原子绑定、Float32 WebGPU 双生产视口和 Main +Volume 属性重开已有真实证据;GPU demand paging、联合保存重开、完整材质、大 bundle/OOM 和 +desktop/Chromium 发布 golden 仍阻断。handle-local 专用 gizmo 已接通,新字体导入等剩余项按 `docs/status/N-015.md` 和 `docs/VDB_NANOVDB_WEBGPU_IMPLEMENTATION_PLAN.md` 推进。 ### PBR-001 至 PBR-012 模型物理渲染(核心切片 done_current_scope,资产/高级渲染安全门 in_progress) @@ -203,10 +204,11 @@ HDR/EXR、多 tile 采样、Offscreen context-loss、真实 WebGPU renderer、 ### N-026 当前发布实况 `docs/status/release-evidence.json` 已生成 13 条成功 command/output/artifact-hash 记录;其中 -VDB 边界记录没有设置发布 true 字段,只证明 Phase 0 协议门。 +VDB 专项记录覆盖真实 converter、server job、HTTP/OPFS 和有界 WebGPU 当前切片,但尚未设置 +发布 true 字段,不能替代 demand paging、大 bundle/OOM 和发布 golden。 `test:release-evidence` 计算为 15 个缺失并保持 `BLOCKED`。其中 3 个是实际证据字段 `performance.geometry10M`、`performance.longMedia`、`faults.oom`,其余 12 个来自仍为 -`BLOCKED` 的 N-016 至 N-026 family。浏览器范围仅为 Chromium。 +`BLOCKED` 的 N-015 至 N-026 family。浏览器范围仅为 Chromium。 ## 6. 当前验收命令 diff --git a/docs/VDB_NANOVDB_WEBGPU_IMPLEMENTATION_PLAN.md b/docs/VDB_NANOVDB_WEBGPU_IMPLEMENTATION_PLAN.md index 80970a7b..2ff192f3 100644 --- a/docs/VDB_NANOVDB_WEBGPU_IMPLEMENTATION_PLAN.md +++ b/docs/VDB_NANOVDB_WEBGPU_IMPLEMENTATION_PLAN.md @@ -1,6 +1,6 @@ # VDB -> NanoVDB -> WebGPU 实施方案 -更新时间:2026-08-13 +更新时间:2026-08-14 ## 1. 范围与完成定义 @@ -181,12 +181,14 @@ transmittance termination 和 NaN 防护。shader 不能通过越界 buffer read 点比较值与 active/inactive 状态。状态:`in_progress`;Float32 CPU/WGSL 与 native sample 已逐点 一致,Float16/Vec 仍保持阻断。 - `VDB-032`:实现 GPU page allocator、storage buffer upload、indirection、resident LRU 和 - dispose;每页上传前已通过 chunk hash。`BLOCKED`。 + dispose;每页上传前已通过 chunk hash。状态:`in_progress`;页表、驻留预算、LRU/dispose + 与有界 paged upload 已落地,按视口需求从 OPFS/HTTP 逐页调入并在缺页后继续渲染仍阻断。 - `VDB-033`:实现对象 bounds raycast、front-to-back ray marching、步长/early exit 和深度合成。 状态:`in_progress`;有界正交 bounds、front-to-back integration、early exit 和确定性 96x96 Chromium 图像已完成,生产相机深度合成待接入。 -- `VDB-034`:接入主线程/Offscreen renderer 的相同 volume scene delta;device loss 后重建已 - 验证页面。`BLOCKED`。 +- `VDB-034`:接入主线程/Offscreen renderer 的相同 volume scene delta;状态:`done_current_scope`; + 双生产视口已消费相同 hash-bound asset 并输出非空像素。生产 Offscreen WebGPU device-loss + 自动重建和 demand-page 恢复继续由故障门阻断。 ### Phase 4:材质、Main 与导出 @@ -234,7 +236,8 @@ npm --prefix web run test:vdb-faults 阶段停止条件: - 新增资源若无许可证/来源/hash:不得进入 VDB catalog 或 golden。 -- desktop converter 已构建;server job API 未实现时 `SERVER_CONVERSION` 保持 `BLOCKED`。 +- desktop/server converter 已构建并有 hash 等价证据;未配置受控 endpoint 时运行时 + `SERVER_CONVERSION` 仍保持 `BLOCKED`。 - 无 CPU reference sample 对照:WGSL traversal 不得进入 `READY`。 - 仅能显示 box/point proxy:体渲染仍为 `BLOCKED`。 - 未验证 material mapping、Main 保存重开或 desktop/Chromium golden:N-015 与 N-019 仍为 diff --git a/docs/status/N-015.md b/docs/status/N-015.md index 05d24579..4531cd0b 100644 --- a/docs/status/N-015.md +++ b/docs/status/N-015.md @@ -1,7 +1,7 @@ # N-015 非 Mesh 几何数据块 状态:`BLOCKED / in_progress`(VDB core 已覆盖 server、OPFS、Float32 WebGPU 与 Main 属性重开; -生产视口、高级材质、分页和发布 golden 仍阻断) +GPU demand paging、高级材质、联合重开和发布 golden 仍阻断) 更新时间:2026-08-14 @@ -14,8 +14,8 @@ topology editor。 Volume 采用“桌面/服务端 OpenVDB 转 NanoVDB,浏览器分块读取并以 WebGPU 渲染”的固定架构。 浏览器不直接解码 OpenVDB;当前已完成真实资源 catalog、独立 OpenVDB 13 -> NanoVDB 32 desktop converter、受控 server job、转换/清单/分块协议、OPFS 绑定/重开、Float32 CPU/WGSL 树遍历、 -有界体积积分和 Volume Main 属性保存重开。主线程/Offscreen 生产视口、高级 grid 材质、GPU -分页和发布 golden 尚未完成,因此 N-015 整体保持 `BLOCKED`。 +有界体积积分、主线程/Offscreen 生产视口和 Volume Main 属性保存重开。GPU demand paging、 +高级 grid 材质、联合重开和发布 golden 尚未完成,因此 N-015 整体保持 `BLOCKED`。 | 数据族 | Reader | Web 预览 | 当前门 | | --- | --- | --- | --- | @@ -25,7 +25,7 @@ converter、受控 server job、转换/清单/分块协议、OPFS 绑定/重开 | Metaball | 元素类型、位置、半径、尺度 | bounded sphere proxy;depsgraph implicit mesh | `READY` | | PointCloud | position/radius/POINT 属性 | WNM 分块 Points | `READY`(空数据为 `summary-only`) | | Curves/Hair | position/radius/curve/POINT 属性 | WNM 分块 Points/curve line | `READY`(缺数据阻断) | -| Volume | path/grid metadata + VDB/NanoVDB 转换契约 | WebGPU core 可渲染真实 Float32 density;生产视口未接入 | `BLOCKED` | +| Volume | path/grid metadata + VDB/NanoVDB 转换契约 | WebGPU core 可渲染真实 Float32 density;双生产视口已接入 | `BLOCKED`(paging/material/golden) | ## 已实现任务 @@ -152,6 +152,11 @@ npm --prefix web run test:nonmesh-interaction npm --prefix web run test:vdb npm --prefix web run test:vdb-availability npm --prefix web run test:vdb-native +npm --prefix web run test:vdb-server +npm --prefix web run test:vdb-opfs +npm --prefix web run test:vdb-webgpu +npm --prefix web run test:vdb-viewport +npm --prefix web run test:vdb-faults WEB_TEST_PORT=5349 npm --prefix web run test:e2e -- -g "real OPFS quota|reports quota exhaustion" WEB_TEST_PORT=5201 npm --prefix web run test:e2e -- -g "N-015|non-mesh" ``` diff --git a/docs/status/N-026.md b/docs/status/N-026.md index 4baea0f8..25df1e59 100644 --- a/docs/status/N-026.md +++ b/docs/status/N-026.md @@ -23,7 +23,7 @@ Chromium 完整套件、离线包/OPFS、SPDX SBOM、1M geometry、simulation ca PointCloud/Curves/Hair 共 7 对象已通过 GLB/USDA desktop round-trip。Volume/VDB 已重新纳入, 当前已有真实资源/license/hash、OpenVDB 13->NanoVDB 32 desktop 转换、manifest/range 和确定性 证据;server job、OPFS 重开、Float32 WebGPU core 和 Main Volume 属性保存重开已有专项证据, - 生产视口、GPU paging、GLB/USD loss 和 desktop/Chromium 发布 golden 仍计为阻断。 + 双生产视口已接入;GPU demand paging、GLB/USD loss、联合重开和 desktop/Chromium 发布 golden 仍计为阻断。 6. 当前发布包已通过本地 third-party notices、Blender/Three license 文件、无远程运行时依赖、 非空 SHA-256 manifest、SPDX 2.3 lockfile/vendored SBOM、对应源码提供和离线二进制/源码包 确定性复建;100k/1M decimate、5 类损坏 blend 和 archive 高压缩比拒绝有实际命令记录。 diff --git a/docs/web/dependency-matrix.md b/docs/web/dependency-matrix.md index 1e3a0e19..5311d6e9 100644 --- a/docs/web/dependency-matrix.md +++ b/docs/web/dependency-matrix.md @@ -15,8 +15,8 @@ move from `待验证` only after a task adds a build or browser regression test. | Blender `draw/gpu` viewport | 关闭首期 | Three.js is the browser renderer | W-013, W-050 | | Python runtime and automatic `.blend` scripts | 关闭首期 | security and package-size boundary | W-117 | | Cycles, CUDA/OptiX, Embree | 关闭首期 | server-side or native rendering only | roadmap non-goal | -| OpenVDB | 浏览器关闭;桌面/服务端转换目标 planned | 读取 `.vdb` 并输出受校验 NanoVDB;不得链接进浏览器 WASM | N-015 VDB-010~014 | -| NanoVDB | 浏览器仅消费格式 | 分块 range + WebGPU sparse volume;当前协议已落地,renderer 阻断 | N-015 VDB-003~034 | +| OpenVDB | 浏览器关闭;桌面/服务端转换目标保留 | 真实 OpenVDB 13 -> NanoVDB 32 desktop/server 转换;不得链接进浏览器 WASM | N-015 VDB-010~014,native/server hash 等价门 | +| NanoVDB | 浏览器仅消费格式 | HTTP/OPFS 分块 + Float32 WebGPU sparse volume;双生产视口已接入,demand paging/material/golden 阻断 | N-015 VDB-003~034 | | USD, FFmpeg | 关闭首期 | server-side or later format modules | W-021 | | React + TypeScript | 保留 | application UI and state | W-010 | | Three.js (vendored) | 保留 | WebGL2 viewport and scene adapter; runtime has no CDN dependency | W-013, W-050 | diff --git a/tools/web/check-status-consistency.mjs b/tools/web/check-status-consistency.mjs new file mode 100644 index 00000000..337e54d9 --- /dev/null +++ b/tools/web/check-status-consistency.mjs @@ -0,0 +1,52 @@ +import assert from "node:assert/strict"; +import crypto from "node:crypto"; +import fs from "node:fs"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../.."); +const read = (relativePath) => fs.readFileSync(path.join(root, relativePath), "utf8"); +const ledgerBytes = fs.readFileSync(path.join(root, "docs/status/parity-ledger.json")); +const ledger = JSON.parse(ledgerBytes); +const report = JSON.parse(read("docs/status/release-evidence.json")); +const overview = read("docs/PROJECT_STATUS_AND_NEXT_WORK.md"); +const parity = read("docs/BLENDER_5_2_WEB_FEATURE_PARITY.md"); +const n015 = read("docs/status/N-015.md"); +const n026 = read("docs/status/N-026.md"); +const vdbPlan = read("docs/VDB_NANOVDB_WEBGPU_IMPLEMENTATION_PLAN.md"); + +const expectedFamilies = Array.from({ length: 12 }, (_, index) => `N-${String(index + 15).padStart(3, "0")}`); +assert.deepEqual(ledger.families.map((family) => family.id), expectedFamilies, "parity ledger family order or coverage drifted"); +assert.deepEqual(report.families, ledger.families, "release evidence family snapshot is stale"); +assert.equal( + report.sourceSha256, + crypto.createHash("sha256").update(ledgerBytes).digest("hex"), + "release evidence source hash is stale", +); + +const blockedFamilies = ledger.families.filter((family) => family.status === "BLOCKED").map((family) => family.id); +const falseEvidence = []; +for (const [group, values] of Object.entries(report.evidence)) { + if (group === "records") continue; + for (const [key, value] of Object.entries(values)) if (value === false) falseEvidence.push(`${group}.${key}`); +} +const missingCount = blockedFamilies.length + falseEvidence.length; +assert.equal(blockedFamilies.length, 12, "this baseline expects N-015 through N-026 to remain explicitly blocked"); +assert.deepEqual(falseEvidence.sort(), ["faults.oom", "performance.geometry10M", "performance.longMedia"]); +assert.equal(missingCount, 15); + +for (const document of [overview, parity]) { + assert.match(document, /13 条(?:成功 )?(?:command\/output\/artifact-hash )?(?:有效)?记录|13 条有效记录/); + assert.match(document, /15 个缺失/); + assert.match(document, /N-015 至 N-02[56]/); +} +for (const document of [overview, n015, n026, vdbPlan]) { + assert.match(document, /desktop\/server converter|desktop\/server OpenVDB|desktop\/server converter|server job/); + assert.match(document, /双生产视口|主线程\/Offscreen 生产视口|主线程\/OffscreenCanvas/); + assert.match(document, /demand paging|demand-page/); + assert.match(document, /发布 golden|desktop\/Chromium.*golden/); +} + +process.stdout.write( + `status-consistency-ok families=${ledger.families.length} blocked=${blockedFamilies.length} evidenceRecords=${report.evidence.records.length} missing=${missingCount}\n`, +); diff --git a/web/package.json b/web/package.json index 5c8f4559..bbcba083 100644 --- a/web/package.json +++ b/web/package.json @@ -75,6 +75,7 @@ "release:sbom": "node ../tools/web/generate-sbom.mjs", "release:evidence": "node ../tools/web/collect-release-evidence.mjs", "test:release-evidence": "node ../tools/web/check-release-evidence.mjs", + "test:status-consistency": "node ../tools/web/check-status-consistency.mjs", "release:offline": "npm run build && node ../tools/web/check-offline-reproducibility.mjs", "diagnose:depsgraph": "node ../tools/web/diagnose-depsgraph.mjs" },