Uniform Module
src/uniform/ contains the lightweight abstraction we use for WebGPU uniform buffers. It wraps a GPU buffer, keeps a CPU-side cache, enforces size/alignment rules, and exposes helpers for packing data into std140-friendly layouts. The renderer, preprocessors, and managers all rely on these helpers to keep camera and render-setting uniforms in sync every frame.
Responsibilities
- Normalize any
ArrayBuffer/typed-array input into a GPU uniform buffer with the correct usage flags. - Maintain a CPU-side copy of the data so multiple updates can be batched before a single
flush()call. - Provide a shared
bindGroupLayoutso pipelines can bind uniforms without recreating layouts. - Offer packing/alignment helpers (
UniformUtils) for vec/mat data that must obey WebGPU’s 16-byte rules.
Components
| Component | Path | Purpose |
|---|---|---|
UniformBuffer |
uniform_buffer.ts |
Concrete implementation of IUniformBuffer. Owns the GPU buffer, bind group, cached data, and flush/clone/destroy methods. |
UniformUtils |
index.ts |
Static helpers for aligning sizes and packing vec/mat data with padding. |
IUniformBuffer, UniformConfig, UniformData |
index.ts |
Interfaces and types shared across modules. |
Data flow
CPU struct (camera/settings/params)
�?setData()
UniformBuffer cache (ArrayBuffer)
�?flush()
GPU uniform buffer �?shaders (via cached bind group)
setData(view)copies typed-array bytes into the CPU cache (size must match exactly).flush(device?)uploads the cached bytes viaqueue.writeBuffer. If no device is passed, it uses the one provided at construction.datagetter returns a copy of the cache when debugging or hot-reloading settings.
Usage example
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);
For small structs (e.g., render settings) you can build a Float32Array, call setData, and flush once per frame. Batch multiple uniforms by writing all caches first, then calling flush() on each before encoding compute/render passes.
Integration points
- Renderer (
GaussianRenderer) �?holdscameraUniforms,settingsUniforms,modelParamsUniforms. Every frame it packs data viaUniformBuffer.setData()and flushes before dispatching preprocess or render passes. - Preprocessor (
GaussianPreprocessor) �?packs camera and render settings intoUniformBuffers prior to each compute pass; ONNX paths overwrite sections viaqueue.copyBufferToBufferusing the same buffers. - Point cloud model params �?each
PointCloudowns aUniformBuffer(modelParamsUniforms) that shaders read in preprocess/render pipelines.
Because uniforms sit on the hot path for every command buffer, the module keeps the API minimal: construct once, reuse the GPU buffer, and only touch the CPU cache when values actually change.
Related Docs
- Architecture – Layout diagrams, std140 padding strategies, and binding lifecycle.
- API Reference –
UniformBuffermethods, config interfaces, and helper utilities. - Renderer Module – Shows how camera/settings uniforms are consumed per frame.
- Preprocess Module – Details the compute uniforms fed to projection shaders.
- Point Cloud Module – Explains how per-model parameter buffers are produced.