跳转至

Uniform模块

src/uniform/ 包含我们用于 WebGPU 统一缓冲的轻量级抽象。它封装了一个 GPU 缓冲,保留一个 CPU 端缓存,强制执行大小/对齐规则,并暴露用于将数据打包成 std140 友好布局的辅助函数。渲染器、预处理器和管理器都依赖这些辅助函数来保持相机和渲染设置 Uniform 在每一帧同步。

职责

  • 将任何 ArrayBuffer/类型化数组输入规范化为具有正确用法标志的 GPU 统一缓冲。
  • 在 CPU 端维护数据副本,以便在单次 flush() 调用之前可以批量处理多个更新。
  • 提供共享的 bindGroupLayout,以便管线可以绑定 Uniform 而无需重新创建布局。
  • 提供打包/对齐辅助函数 (UniformUtils),用于必须遵守 WebGPU 16 字节规则的 vec/mat 数据。

组件

组件 路径 目的
UniformBuffer uniform_buffer.ts IUniformBuffer 的具体实现。拥有 GPU 缓冲、绑定组、缓存数据以及 flush/clone/destroy 方法。
UniformUtils index.ts 用于对齐大小和使用填充打包 vec/mat 数据的静态辅助函数。
IUniformBuffer, UniformConfig, UniformData index.ts 跨模块共享的接口和类型。

数据流

CPU 结构体 (camera/settings/params)
   └─ setData()
UniformBuffer 缓存 (ArrayBuffer)
   └─ flush()
GPU 统一缓冲 → 着色器 (通过缓存的绑定组)
  • setData(view) 将类型化数组字节复制到 CPU 缓存中(大小必须完全匹配)。
  • flush(device?) 通过 queue.writeBuffer 上传缓存的字节。如果未传递 device,则使用构造时提供的 device。
  • data getter 在调试或热重载设置时返回缓存的副本。

使用示例

import { UniformBuffer, UniformUtils } from 'src/uniform';

const cameraBytes = UniformUtils.createAlignedBuffer(272);
const cameraUniform = new UniformBuffer(device, cameraBytes, 'camera');

function updateCamera(cameraData: ArrayBufferView) {
  cameraUniform.setData(cameraData);
  cameraUniform.flush();
}

renderPass.setBindGroup(0, cameraUniform.bindGroup);

对于小型结构体(例如渲染设置),您可以构建一个 Float32Array,调用 setData,并在每帧 flush 一次。通过先写入所有缓存,然后在编码计算/渲染 Pass 之前对每个缓冲调用 flush() 来批量处理多个 Uniform。

集成点

  • Renderer (GaussianRenderer) – 持有 cameraUniforms, settingsUniforms, modelParamsUniforms。每帧它通过 UniformBuffer.setData() 打包数据,并在分派预处理或渲染 Pass 之前 flush。
  • Preprocessor (GaussianPreprocessor) – 在每个计算 Pass 之前将相机和渲染设置打包到 UniformBuffer 中;ONNX 路径使用相同的缓冲通过 queue.copyBufferToBuffer 覆盖部分区域。
  • Point cloud model params – 每个 PointCloud 拥有一个 UniformBuffer (modelParamsUniforms),着色器在预处理/渲染管线中读取该缓冲。

由于 Uniform 位于每个命令缓冲的关键路径上,该模块保持 API 最小化:构造一次,重用 GPU 缓冲,并且仅在值实际更改时才触摸 CPU 缓存。

相关文档