Files
workinf_Blender_Wasm/docs/PBR_RENDERING_IMPLEMENTATION_PLAN.md
2026-08-12 04:47:48 -04:00

12 KiB
Raw Blame History

Web Blender PBR 渲染实现与任务分解

更新日期2026-08-09

1. 目标和声明边界

目标是在浏览器 3D Viewport 中提供与 Blender Principled 工作流一致、可保存、可重开的 PBR 预览。材质参数必须来自 Blender Main经 SceneIR 传输并由主线程和 OffscreenCanvas Worker 使用相同映射,禁止只修改 Three.js 临时状态。

当前能力称为 physical-v1,不是 Cycles、EEVEE 或 Blender Shader Node 的逐像素等价实现。 它保证的是有界 Principled 参数、线性色彩输入、sRGB 输出、ACES Filmic tone mapping、 World exposure、场景灯光和有界 PCF 阴影的一致 WebGL 渲染。未声明节点、谱渲染、光程、体积、 次表面、多次散射和离线 path tracing 必须继续结构化阻断或降级并给出 warning。

2. 权威数据流

Blender Main
  -> .blend writer/save/reopen
  -> native blend reader
  -> SceneIR MaterialIR/LightIR/WorldIR
  -> transferable mesh buffers
  -> shared pbr.ts mapping
     -> main-thread WebGLRenderer
     -> OffscreenCanvas render Worker

编辑链路为Inspector 控件 -> setMaterialPrincipled -> EngineWorker -> Blender Main 节点 socket -> 新 revision SceneIR -> 视口重建。任何新增参数必须同时通过命令校验、Main 写回、 reader、SceneIR parser、保存重开和双后端验收。

3. Blender 到 Web 的材质映射

Blender 5.2 Principled 输入 SceneIR Three.js 范围/说明
Base Color baseColor color 线性 RGBalpha 独立处理
Roughness roughness roughness [0,1]
Metallic metallic metalness [0,1]
IOR ior ior 当前限定 [1,2.333]
Specular IOR Level specularIORLevel specularIntensity Blender 中性值 0.5 映射到 Three 中性值 1.0;高半区有界截断
Transmission Weight transmissionWeight transmission [0,1],使用物理透射 pass
Coat Weight coatWeight clearcoat [0,1]
Coat Roughness coatRoughness clearcoatRoughness [0,1]
Emission Color emissionColor emissive 线性 RGB
Emission Strength emissionStrength emissiveIntensity [0,1000000]
Alpha alpha opacity/transparent/depthWrite alpha blend 时关闭 depth write

材质选择高亮保存原始 emission 和强度,取消选择后恢复,不再破坏自发光材质。所有网格、 实例和 LOD 都启用一致的 cast/receive shadow 标志。

4. 色彩、灯光和阴影

  • Blender/SceneIR 数值按线性工作空间进入材质和灯光。
  • WebGL 输出固定为 SRGBColorSpacetone mapping 固定为 ACESFilmicToneMapping
  • WorldIR.exposure 按摄影 stop 转换为 2 ** exposure,并限制在 [-8,8]
  • 无场景灯时使用低强度中性 Hemisphere fill 和有阴影的 key light确保空场景可检查。
  • POINT、SUN、SPOT、AREA 均从 LightIR 创建。SUN/SPOT 根据 Blender 本地 -Z 方向创建真实 Three target不再错误地全部指向世界原点。
  • SUN、SPOT、POINT 使用 PCFShadowMap,第一质量档为 1024 平方 shadow map并设置 有界 bias、normal bias、near/far。AREA 受 Three WebGL 能力限制,当前不声明阴影等价。
  • 主线程与 Worker 暴露 data-pbr-profiledata-tone-mappingdata-shadow-map,供 自动化测试核对真实后端配置。

5. 资产和纹理边界

当前 SceneIR 已表达 UV、Image Texture、Normal Map、packed image 和资源状态,但纹理像素 进入 GPU 的链路必须继续遵守 EngineWorker/StorageWorker 权威模型。浏览器渲染器不得根据 .blend 内路径自行访问文件系统或网络。

PBR-007 已建立 GPUTextureAsset 只读载荷:assetIdimageId、SHA-256、MIME、尺寸、 颜色空间、用途、UDIM tile 和 ArrayBuffer 必须通过字节数、64 MiB 单图、16384 维度和 SHA-256 校验后才可进入 ImageBitmap/Three Texture。主线程与 Offscreen Worker 共享同一 GPUTextureStore 逻辑,载荷状态和拒绝字节数可观测;路径仍只能由 EngineWorker/StorageWorker 解析,浏览器不得访问 .blend 内路径。当前不把 context-loss 自动恢复、mipmap/anisotropy 策略和完整 UV Map 节点映射误报为完成。

6. 质量档和性能预算

档位 阴影 DPR 透射 目标
Low 关闭或 512 1 关闭 低内存移动设备
Medium PCF 1024 min(device,1.5) 0.5 分辨率 默认移动/集显
High PCF 1024/2048 min(device,2) 全分辨率 默认桌面

physical-v1 当前实现 High 的有界子集。后续自动降档的输入包括 GPU tier、draw call、 transmission material 数、shadow caster 数、WASM/GPU 内存压力和帧时间 P95。质量切换只能 改变表现质量,不得改变 Main 或保存语义。

7. 任务分解与执行顺序

PBR-001 协议与安全门done

  • PBR-001-A扩展 MaterialIR 五个物理参数,保持旧 snapshot 可解析。
  • PBR-001-B对比例参数验证 [0,1],对 emission strength 设硬上限。
  • PBR-001-C扩展 setMaterialPrincipled,所有字段保持 optional 兼容旧客户端。
  • PBR-001-Dlinked material 继续拒绝写回NaN/Infinity 继续由 native 阻断。

PBR-002 Blender Main authoringdone

  • PBR-002-A自建 Principled 节点补齐五个 Blender 5.2 socket。
  • PBR-002-B命令写入 Base/Roughness/Metallic/IOR/Specular/Transmission/Coat/Emission。
  • PBR-002-Cnative reader 从真实 socket 读取并生成 SceneIR。
  • PBR-002-DMain round-trip 和 save/reopen 核对每个物理参数误差小于 1e-5

PBR-003 共享物理材质适配器done

  • PBR-003-AMeshPhysicalMaterial 替代两条路径的 Standard/fixed material。
  • PBR-003-B集中 clamp、默认值、透明深度策略和 selection emission 恢复。
  • PBR-003-C主线程、Worker、实例和 LOD 使用同一映射。
  • PBR-003-DWorker 恢复 UV、corner color 和多材质 triangle group。

PBR-004 色彩管理和曝光done

  • PBR-004-A线性输入、sRGB output、ACES Filmic。
  • PBR-004-BWorld exposure 按 stop 映射并限制极端值。
  • PBR-004-C通过 canvas profile 属性和像素非空门验证双后端。

PBR-005 灯光和阴影done_current_scope

  • PBR-005-APOINT/SUN/SPOT/AREA 类型映射。
  • PBR-005-B修复 SUN/SPOT 方向 target。
  • PBR-005-CSUN/SPOT/POINT PCF 阴影、bias 和 shadow camera 边界。
  • PBR-005-D待补能量单位校准 fixture、级联太阳阴影、AREA 阴影替代和 caster budget。

PBR-006 材质 Inspectordone_current_scope

  • PBR-006-A增加 IOR、Specular、Transmission、Coat、Coat Roughness、Emission Strength。
  • PBR-006-B应用命令保留 alpha 和 emission color。
  • PBR-006-C待补材质槽选择、emission color、alpha mode、双面和 blend mode 面板。

PBR-007 纹理像素闭环in_progressAssetPayload/解码已完成GPU 生命周期仍有安全门)

  • PBR-007-Adone_current_scoperender-assets.ts 定义 schema v1、SHA-256、MIME/尺寸/字节预算和稳定错误码App 从 requestAsset 生成载荷并同时写入 OPFS。
  • PBR-007-Bdone_current_scopeBase Color/Emission 使用 sRGBNormal/Data 使用 non-color/linear主线程和 Worker 使用相同 GPUTextureStore
  • PBR-007-Cin_progressImageBitmap 解码、旧 Texture dispose、状态回传已完成mipmap、anisotropy、GPU context-loss 恢复和全局显存预算仍未开放。
  • PBR-007-DNormal Map 切线空间、UV Map 选择、wrap/filter 和缺失纹理 fallback。
  • PBR-007-Ein_progress双后端同一载荷正例已覆盖context-loss/Worker crash 后重新上传仍属于 PBR-011 故障注入门。

PBR-008 UDIM 与外部资源in_progressmanifest/阻断已完成,多 tile 采样未声明)

  • PBR-008-Adone_current_scopeUDIMManifest 校验 1001..1999、u/v 坐标、重复 tile、数量上限和 packed 状态;每个 tile 进入同一 SHA-256 载荷。
  • PBR-008-Bin_progress当前只允许单 tile 安全上传,多 tile 返回 UDIM_MULTI_TILE_UNAVAILABLE尚未实现分页、LRU 和 GPU atlas/array 采样。
  • PBR-008-Cdone_current_scopelinked library、外部路径和缺 tile 使用结构化门,禁止任意路径读取。
  • PBR-008-Ddone_current_scopegenerated/sequence/movie 不生成静态 GPU 载荷,保持独立 capability。

PBR-009 IBL 和 World Nodesin_progress有限 raster equirectangular IBL

  • PBR-009-Ain_progresspacked PNG/JPEG equirectangular 环境可经 GPU 载荷、PMREMGenerator 生成反射环境HDR/EXR 解码尚未实现并返回 IBL_FORMAT_UNSUPPORTED
  • PBR-009-Bin_progressWorldIR 已携带 environment image/strength/rotation 字段,当前只消费 strength旋转、跨场景缓存和完整 HDR 色域仍待安全门。
  • PBR-009-Cdone_current_scopebackgroundVisiblescene.environment 生命周期分离,旧 PMREM target 会释放。
  • PBR-009-Ddone_current_scope任意 World Shader Node 不进入纹理上传,保持结构化阻断。

PBR-010 GLB PBR 扩展done_current_scope

  • PBR-010-A已导出 KHR_materials_iortransmissionclearcoatspecularemissive_strength,并保留无完整节点图时的有界 imageIds Base Color/Normal 路径。
  • PBR-010-B桌面 Blender 再导入比较覆盖 8x8 packed texture、骨骼、shape key、动作和材质基础值。
  • PBR-010-C不支持的 Blender 图返回 SHADER_GRAPH_UNMAPPABLE,禁止静默烘焙。
  • PBR-010-Dadvanced extension fixture 已验证桌面 Blender 对 IOR、Specular IOR Level、Transmission、Coat 和 Emission Strength 的导入数值。

PBR-011 性能、容错和跨浏览器planned

  • PBR-011-A100k/1M 三角形下记录 CPU/GPU 帧时、draw call、shader compile 和显存。
  • PBR-011-BChromium 主线程/OffscreenCanvas 的 ACES、transmission 与 shadow 差异矩阵。
  • PBR-011-CWebGL context loss、Worker crash、纹理解码失败和 GPU OOM 故障注入。
  • PBR-011-D自动降档必须可观测且不修改权威数据。

PBR-012 高级渲染in_progress能力查询/阻断协议,运行时家族仍未声明)

  • PBR-012-Adone_current_scopequeryRenderCapability 明确返回 WEBGPU_RENDERER_UNAVAILABLE,没有 WebGPU renderer bundle 时不伪装为 WebGPU。
  • PBR-012-Bdone_current_scope安全门BLOOM/SSAO/SSR/TAA/DOF/MOTION_BLUR 未有真实 pass 时返回 POSTPROCESS_PASS_UNAVAILABLE,未声明假实现。
  • PBR-012-Cdone_current_scope安全门Volume/SSS 返回独立 VOLUME_SHADER_UNAVAILABLE/SUBSURFACE_SHADER_UNAVAILABLE,任意 Shader node 返回 SHADER_NODE_UNSUPPORTED
  • PBR-012-D浏览器 path tracer 若引入,作为独立 Render backend不声称 Cycles 等价。

8. 当前验收

source tools/web/emscripten-env.sh
cmake --build build_web_blender6 --target web_engine -- -j8
bash tools/web/install-web-engine-assets.sh
npm --prefix web run typecheck
npm --prefix web run lint
npm --prefix web test
npm --prefix web run test:authoring-roundtrip
WEB_TEST_PORT=5209 npm --prefix web run test:e2e -- -g "PBR|Principled|local UV|packed raster|OffscreenCanvas"

发布前还要运行完整 E2E、跨浏览器、GLB Blender round-trip 和离线包门。桌面与移动截图必须 检查 canvas 非空、模型构图、材质高光/阴影可见、控件不遮挡以及页面无异常横向溢出。

9. 完成定义

一个 PBR 子任务只有在以下条件全部满足后才能标记 done协议字段可验证Main 可写; 保存重开等价;主线程和 Worker 可渲染;资源可释放;错误稳定且结构化;至少一个正例和一个 边界反例;桌面/移动像素与截图门通过;状态文档同步。仅识别 Blender socket、仅构造 SceneIR 或仅显示 UI 控件都不构成完成。