14 KiB
VDB -> NanoVDB -> WebGPU 实施方案
更新时间:2026-08-13
1. 范围与完成定义
VDB 重新纳入 N-015/N-019/N-023/N-026。产品链路固定为:桌面工具或受控服务端使用
OpenVDB 读取 .vdb,转换为 NanoVDB;浏览器只读取受校验的 .nvdb 分块,并由 WebGPU
执行稀疏树遍历、采样和体积积分。
浏览器 Blender WASM 必须继续保持 WITH_OPENVDB=OFF。WITH_OPENVDB=ON 或
WITH_NANOVDB=ON 只能证明编译/链接选项,不能证明以下能力:
- 外部 VDB 的受限读取、分块上传、失败恢复和缓存淘汰;
- NanoVDB 数据布局与 WGSL 遍历正确;
- density/temperature/color/emission/velocity 的 Blender 材质语义;
.blend保存、转换产物绑定、重开和资源丢失诊断;- 与 Blender 5.2 桌面图像/数值 golden 一致;
- 大体积、损坏输入、OOM、取消和 Chromium WebGPU 性能门。
只有上述链路均有真实资源与自动测试证据时,VDB 才能从 BLOCKED 转为可发布能力。
2. 架构和信任边界
.blend + .vdb
|
| source SHA-256, grid allowlist, budgets
v
Desktop/Server Blender 5.2 + OpenVDB + NanoVDB
|
| deterministic .nvdb + manifest.json + converter identity
v
Project asset store / HTTP Range / OPFS content-addressed cache
|
| contiguous ranges, per-chunk SHA-256, whole-bundle SHA-256
v
Chromium Storage/Render Worker
|
| bounded GPU pages, validated grid ranges and transforms
v
WebGPU storage buffers + WGSL NanoVDB traversal + volume integrator
信任边界如下:
.vdb是不可信输入,只允许进入桌面/服务端转换沙箱;浏览器不加载 OpenVDB。- 转换器输出也不直接信任。浏览器先校验 schema、路径、预算、连续 range、分块 hash 和整包 hash,再允许 GPU 上传。
- manifest 是持久化真源,路径必须位于项目资源根;HTTP 必须返回精确
206 Content-Range, OPFS 必须使用 content-addressed key。 - GPU resident set 独立受限,CPU/网络总包预算不能代替 GPU 预算。
- Main 只保存源绑定、转换版本、产物 hash、grid/material 映射;不能把临时 URL 或未验证 GPU 状态写成已完成资源。
3. 产物与协议
3.1 转换请求
VDBConversionRequestIR 固定记录 schema、job、项目内 .vdb 路径、源字节数/hash、源 grid
清单、选择 grid、量化策略、分块大小和输出 .nvdb 路径。VDBConverterIdentityIR 固定记录
DESKTOP/SERVER、Blender/OpenVDB/NanoVDB 版本和转换器可执行文件 hash。
同一源 hash、转换器 identity、选择 grid、量化和 chunk size 必须产生相同的 bundle hash;分别生成 但语义相同的 OpenVDB fixture 允许因文件 UUID 而有不同源 hash,其 NanoVDB grid/bundle 应一致。 job ID 和输出路径不进入内容键;不能仅以文件名作为缓存键。
3.2 NanoVDB bundle manifest
NanoVDBBundleManifestIR schema 1 记录:
- 源
.vdb与 bundle.nvdb的项目路径、长度和 SHA-256,以及包含 grid/量化/chunk 参数的 canonical conversion request SHA-256; - 每个 grid 的 value type/class/semantic、active voxel、标准 NanoVDB segment 范围、内部 grid payload 范围、index/world bounds、voxel size 和 4x4 index-to-world;文件内 payload 偏移不要求 对齐,上传到 GPU storage buffer 时另行满足 32-byte alignment;
- density/temperature/color/emission/velocity 材质绑定和受限参数;
- 32-byte 对齐、连续覆盖整个 bundle 的 chunks,以及每块 SHA-256;
NANOVDB_STORAGE_BUFFER、GPU page/resident budget 和volume-wgsl-v1语义版本。
首期 GPU value type 白名单为 Float32、Float16、Vec3f32、Vec4f32。Double、Bool、Int、Point
Index、未知 grid class 返回 NANOVDB_GRID_UNSUPPORTED,不进行隐式转换。
3.3 浏览器流送
streamNanoVDBChunks 串行执行 range read -> 分块 hash -> consumer upload,并在每块后报告字节
进度。串行是首期的确定性基线;通过内存峰值和取消测试后才能加入最多 4 路的有界并发。
createHttpNanoVDBRangeSource 只接受 HTTP 206,且 Content-Range 的起点、终点、总长度必须
与 manifest 精确一致。resumable adapter 对临时状态和网络异常做有界重试;response body 中断后
保留已收字节,以相同 ETag 的 If-Range 从精确偏移续传,干净结束的短响应仍直接拒绝。
OPFS 适配器以 bundleSha256/chunkIndex 为 key 原子提交。所有块校验完成后才提交完整 bundle
manifest;中断留下的 staging 数据不会被重开流程发现,重开后的每次 chunk 读取仍重新校验 SHA-256。
4. 材质与渲染语义
首期声明 Principled Volume 有界子集:
| Blender 语义 | NanoVDB/manifest | WebGPU 行为 |
|---|---|---|
| Density | densityGrid + densityScale |
非负消光/散射密度 |
| Temperature | temperatureGrid + scale |
只在 Blackbody emission 开启时采样 |
| Color | colorGrid 或常量颜色 |
线性工作空间散射颜色 |
| Emission | emissionGrid + scale |
线性辐射项;负值钳制并报告 |
| Velocity | velocityGrid |
首期仅保留/报告,motion blur 未验证前不消费 |
| Anisotropy | manifest scalar | Henyey-Greenstein,范围 [-0.99, 0.99] |
首期只开放单 Volume、单散射/吸收积分、线性/最近采样、对象变换和 scene exposure。多重散射、 体积阴影、烟火黑体、motion blur、多个 volume overlap、Cycles 等价保持独立阻断。
WGSL 实现必须包括 NanoVDB header/version/magic 检查、root/internal/leaf address 上界检查、空 节点跳跃、index-to-world/world-to-index、ray-box intersection、自适应步长上限、early transmittance termination 和 NaN 防护。shader 不能通过越界 buffer read 猜测无效节点。
5. 保存与重开
保存流程分两层:
- Blender Main 中的 Volume 保留项目相对
.vdb引用和 grid/material 参数。 - Web project manifest 保存
sourceSha256 -> conversion request -> bundleSha256绑定、转换器 identity、chunk manifest 和 OPFS/object-store 定位信息。
重开时先比较 .blend Volume 引用、源 hash 和 bundle manifest。源改变、converter 改变、bundle
缺失、hash 不符或 shader semantic version 不符均返回结构化 BLOCKED 并要求重转;不能静默
复用旧缓存。保存成功标准包括:清空 Worker、重新打开 .blend、重新发现 bundle、逐块复验、
恢复同一 grid/material 映射并得到相同像素/采样摘要。
6. 详细任务分解
Phase 0:能力声明与协议
VDB-001:删除浏览器伪 decoder 入口,raw.vdb浏览器解码固定返回VDB_CONVERSION_REQUIRED。状态:done_current_scope。VDB-002:实现 source manifest、conversion request、converter identity、路径/hash/预算门。 状态:done_current_scope。VDB-003:实现 NanoVDB bundle/grid/material/GPU/chunk manifest、range plan、分块与整包 hash 校验。状态:done_current_scope。VDB-004:实现串行 range streamer 和严格 HTTP 206 适配器。状态:done_current_scope。VDB-005:能力门分别报告 desktop converter、server converter、stream、WebGPU renderer; 禁止单一布尔值概括全链路。状态:done_current_scope。
Phase 1:真实资源与转换器
VDB-010:在本机资源库收录许可证明确的 tiny smoke、density+temperature、color、level-set、 大稀疏体积和损坏文件;记录来源 URL、许可证、原始 SHA-256。状态:done_current_scope; 资源库为/home/mes123456/resource-library/blender-web-vdb,含 14 条受 hash 约束记录。VDB-011:建立 native/desktop CMake preset,OpenVDB 只在该目标开启;固定 Blender 5.2、 OpenVDB/NanoVDB 版本并生成可执行文件 hash。状态:done_current_scope;desktop target 实际 链接 OpenVDB 13.0/TBB 并生成 NanoVDB 32.9,浏览器仍保持WITH_OPENVDB=OFF。VDB-012:实现 grid inventory 预扫、allowlist、active voxel/内存/输出预算和取消,调用官方 OpenVDB/NanoVDB API 写出确定性.nvdb。状态:done_current_scope;inventory、allowlist、源/输出/ grid/active voxel 预算、LOSSLESS/FP16、report、确定性、cancel-file、timeout 和失败原子清理已验证。VDB-013:实现服务端 job API:content hash 幂等、上传/转换/下载、进度、超时、取消、日志、 不可信输入隔离和输出签名。状态:done_current_scope;当前以 bubblewrap、只读 root、资源限制、 HMAC 构件签名和原子输出为受控本地服务基线。VDB-014:桌面与服务端对同一 fixture 的 manifest/bundle hash 相同;版本变化必须导致缓存 key 变化。状态:done_current_scope;语义相同的 VDB、官方 sphere 重转及桌面/隔离服务端 转换均得到相同 NanoVDB hash。
Phase 2:存储与流送
VDB-020:实现项目 asset manifest 和 source/bundle binding,支持 source hash 变化失效。 状态:done_current_scope。VDB-021:实现 OPFS range source、staging/journal/atomic commit、重启发现和 LRU page cache。 状态:done_current_scope;已验证真实 bundle、取消清理、Worker 重开、tamper gate 和 bundle LRU。VDB-022:实现 HTTP Range 重试、ETag/If-Range、断点续传、重复/乱序/短响应拒绝。 状态:done_current_scope;临时状态/网络异常重试、稳定 ETag、response-body 精确偏移续传、 ETag 改变、错位Content-Range、短响应和逐块 hash 均有 Chromium 故障门。VDB-023:增加网络中断、Worker terminate、quota、tamper、manifest rollback 测试。 状态:done_current_scope;网络/body 中断、Worker terminate、真实 OPFS quota、chunk tamper、 manifest rollback、incomplete staging recovery 和旧 bundle 保持均已验证。VDB-024:在 512 MiB CPU、1 GiB bundle、512 MiB GPU 上限下验证峰值;不得整包复制到 JS heap。planned。
Phase 3:WebGPU NanoVDB
VDB-030:加入 Chromium WebGPU capability probe、adapter/device limits 和 device loss 状态机。 状态:done_current_scope;真实 adapter/device limit probe、device loss、device 重建和重传后 固定点 sample 一致已完成;生产视口资源重建仍归VDB-034。VDB-031:实现 NanoVDB Float/Vec leaf traversal WGSL 和 CPU reference sampler;用固定 index 点比较值与 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。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。
Phase 4:材质、Main 与导出
VDB-040:读取 Blender Volume/Principled Volume 节点并生成显式 material mapping/loss report。 状态:in_progress;density、常量 color/emission、anisotropy、nearest/linear 已映射, color/temperature/emission grid 和 velocity 明确生成 loss。VDB-041:density/temperature/color/emission/anisotropy 的 Main writer、undo/redo 和原子事务。 状态:in_progress;Volume source/display/interpolation/step/velocity Main 写回、undo/redo、保存重开 已完成,Principled Volume 完整节点事务仍阻断。VDB-042:保存.blend与 Web asset binding,清空 Worker 后重开并重新流送。BLOCKED。 状态:in_progress;Main Volume 保存重开与 OPFS asset binding/Worker 重开分别通过,尚待生产视口 联合重开闭环。VDB-043:GLB 明确报告 Volume 无核心映射;USD 仅在 desktop USD/OpenVDB 路径真实可用时 写入 field asset,不把 bounds proxy 当体积导出。BLOCKED。
Phase 5:真实验收与发布
VDB-050:desktop OpenVDB -> NanoVDB grid count/name/type/transform/bounds/value sample golden。VDB-051:Blender 5.2 与 Chromium WebGPU 的至少 3 个视角像素 golden,分别比较 alpha、 transmittance、color,记录容差与色彩空间。VDB-052:64 MiB/512 MiB/1 GiB sparse bundle 的首帧、渐进清晰、峰值 CPU/GPU 和取消门。VDB-053:损坏 magic/version/tree offset/hash、zip bomb 等价超预算、NaN transform、设备丢失、 网络中断和 OOM 门。VDB-054:保存重开、资源缺失、源变更重转、旧 schema migration、离线 OPFS 重开。VDB-055:N-026 证据记录包含真实转换器、资源、Chromium WebGPU、desktop golden 和构件 hash。
Phase 5 全部任务当前为 BLOCKED,不能由 Phase 0 的协议 fixture 代替。
7. 验收命令与停止条件
当前可运行门:
npm --prefix web run typecheck
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
阶段停止条件:
- 新增资源若无许可证/来源/hash:不得进入 VDB catalog 或 golden。
- desktop converter 已构建;server job API 未实现时
SERVER_CONVERSION保持BLOCKED。 - 无 CPU reference sample 对照:WGSL traversal 不得进入
READY。 - 仅能显示 box/point proxy:体渲染仍为
BLOCKED。 - 未验证 material mapping、Main 保存重开或 desktop/Chromium golden:N-015 与 N-019 仍为
BLOCKED。 - Chromium 是当前唯一浏览器门;不配置 Firefox/WebKit,也不把未测浏览器写成兼容。