Point Cloud Module Architecture
The point cloud module is the canonical bridge between data ingestion and GPU execution. It receives GenericGaussianPointCloudTS objects (from IO or ONNX paths), instantiates the GPU buffers required by preprocess and render pipelines, tracks per-model uniforms, and exposes bind groups plus dynamic hooks so every downstream stage can consume a consistent contract.
Pipeline Map
┌──────────────┐ ┌───────────────────────────┐ ┌────────────────────┐
│ IO / ONNX │ ───► │ PointCloud / DynamicPC │ ───► │ Preprocess Compute │
│ (data source)│ │ • GPU buffers │ │ • depth sort pass │
└──────────────┘ │ • Uniform + model params │ └─────────┬──────────┘
│ • Bind group handles │ │
└───────────────────────────┘ ▼
┌────────────────────────┐
│ Renderer / Indirect MW │
└────────────────────────┘
Static assets follow the IO path while real-time scenes inject GPU buffers directly through DynamicPointCloud. Both converge on identical bind group layouts, enabling the preprocess, sorting, and renderer modules to remain agnostic to data provenance.
Construction Path
- Metadata ingestion –
PointCloudreads counts, SH degree, bounding boxes, and optionalcenter/upvectors from theGenericGaussianPointCloudTSimplementation. These values seed public fields such asnumPoints,shDeg,bbox, and orientation helpers. - Gaussian & SH storage – Unless
externalBuffersis supplied, CPU buffers are uploaded into WebGPU buffers labelledgaussians/storageandsh/storagewith usageSTORAGE | COPY_DST(point_cloud.tsconstructor). - Projected splat buffer – A dedicated 2D buffer (
splat2DBuffer) is allocated usingBUFFER_CONFIG.SPLAT_STRIDEto ensure enough space for projected attributes, sort keys, and indirect draw metadata (GPUBufferUsage.STORAGE | COPY_SRC | COPY_DST | INDIRECT). - Uniform buffers – Two
UniformBufferinstances are spawned: uniforms: 16 bytes for point count and SH degree, consumed by preprocess shaders.modelParamsUniforms: 128 bytes aligned to 16-byte boundaries, carrying transforms, offsets, shading controls, and precision descriptors.- Bind groups – The module fetches cached layouts from
getBindGroupLayout/getRenderBindGroupLayoutand immediately createspointcloud/bg(compute) pluspointcloud/render/bg(render) instances so pipelines can bind them without additional wiring.
Bind Group Contract
- Compute (
@group(0)) binding 0: Gaussian storage (read-only-storage).binding 1: SH storage (read-only-storage).binding 2: 2D splat buffer (storage– also used as indirect target).binding 3: Draw uniforms (uniform).- Render (
@group(0)) binding 2: Read-only access to the projected splat buffer for vertex-stage rasterization.
Layouts live inside a WeakMap cache per GPUDevice, guaranteeing deterministic binding order and avoiding layout churn when multiple point clouds coexist.
Model Parameter Uniform
PointCloud keeps the authoritative transform/configuration block in CPU memory and writes it through updateModelParamsBuffer (also called by setTransform and updateModelParamsWithOffset). The structure mirrors the WGSL expectation:
- Bytes 0–63: Column-major model matrix.
- Bytes 64–95: Metadata for multi-instance rendering (
baseOffset,numPoints) and shading controls (gaussianScaling,maxShDeg,kernelSize,opacityScale,cutoffScale,rendermode). - Bytes 96–119: Precision descriptors (
gaussDataType,colorDataType, per-channel scales and zero-points) used to decode quantized INT8/UINT8 data in shaders. - Bytes 120–127: Reserved padding.
Because the buffer is rebuilt whenever updateModelParamsBuffer runs, downstream systems simply keep a reference to modelParamsUniforms.buffer and write it into whichever bind group is responsible for model uniforms in the renderer.
DynamicPointCloud Flow
DynamicPointCloud inherits every capability from PointCloud but swaps the constructor contract:
- Accepts pre-existing
GPUBufferhandles (gaussianBuffer,shBuffer) plus an optionalcountBufferdescribing the live draw count for indirect pipelines. - Computes the SH degree from the provided
colorChannels(3, 4, 12, 27, 48) and exposes thecolorMode(rgbif 4 channels, otherwisesh). - Stores optional
precisionInfo(gaussian/color) so quantization metadata can be injected into the model params block withsetPrecisionForShader. - Manages an embedded
TimelineController, exposing helpers such asstartAnimation,setTimeScale,setTimeUpdateMode,setAnimationIsLoop, andresetFrameTimeso animation managers can drive ONNX models with consistent timing semantics. - The asynchronous
updatemethod composes the camera matrix with the model transform, computes an adjusted frame time (respecting loop/offline preview modes), and invokes the ONNX generator, which writes directly into the bound GPU buffers—no CPU copies in the steady state.
Precision & Buffer Swapping
replaceStorageBuffers(base class) swaps Gaussian/SH buffers and rebuilds the compute bind group while preserving the projected splat buffer and uniforms.applyFP16(dynamic subclass) is a convenience wrapper that replaces buffers, marks both gaussian/color precisions asfloat16, and refreshes shader metadata.setPrecisionForShaderrewrites bytes 96–119 of the model params buffer usingDataViewsetters so shaders can decode INT8/UINT8 payloads on demand.
These pathways let the preprocess module run conversion shaders (e.g., convert_precision.wgsl) and then rebind the results without re-instantiating PointCloud.
Resource Lifecycle & Diagnostics
getSplatBufferpublishes the raw GPU storage plus metadata, which the preprocess module uses to drive compute dispatch sizing.- Parameter setters (
setGaussianScaling,setMaxShDeg,setKernelSize,setOpacityScale,setCutoffScale,setRenderMode) update cached state and reuseupdateModelParamsBufferto flush changes. DynamicPointCloud.countBuffer()exposes the optional draw-count buffer so the renderer can configure indirect draws.getPerformanceStatssurfaces timeline-related telemetry (isPlaying, animation speed, ONNX linkage) for UI overlays or debugging tools.disposecurrently clears timeline listeners; GPU buffers remain externally owned to avoid double-freeing shared resources.
Data Flow Summary
[GenericGaussianPointCloudTS] ──► PointCloud ctor ──► {gaussianBuffer, shBuffer, splatBuffer}
│
├─► UniformBuffer (draw)
└─► UniformBuffer (model params)
[ONNX Generator] ──► DynamicPointCloud.update ──► direct GPU writes ──► same bind groups
By standardising buffer lifetimes, bind group layouts, and precision metadata, the point cloud module ensures that IO loaders, ONNX pipelines, preprocess kernels, sorters, and renderers all agree on a single contract, keeping Visionary’s WebGPU stack predictable and extensible.