Utils Module API Reference
This reference covers every public helper exposed from src/utils/, grouped by capability.
Table of Contents
- GPU Utilities
- Debugging & Profiling
- Float16 & SH Packing
- Mathematical Utilities
- Geometry Helpers
- Transform Constants
- Renderer & Environment Helpers
- Type Definitions
GPU Utilities
align4(n: number): number
Bitwise-aligns n to the next 4-byte boundary. Required for WebGPU buffer copies.
align8(n: number): number
Bitwise-aligns n to the next 8-byte boundary. Required for buffer mapping.
readWholeBuffer(device, src, byteLength, srcOffset = 0): Promise<Uint8Array>
Reads byteLength bytes from src into CPU memory. Internally:
1. Rounds copy/map sizes via align4/align8
2. Allocates a staging buffer (COPY_DST | MAP_READ)
3. Copies data and waits for GPU queue completion if supported
4. Maps, slices the requested region, and destroys the staging buffer
Throws if src lacks GPUBufferUsage.COPY_SRC.
dumpU32(bytes: Uint8Array): void / dumpHex(bytes: Uint8Array): void
Log helpers for visualizing readback data either as Uint32 values or hex strings.
keyToNum(code: string): number | undefined
Maps "Digit0"…"Digit9" keyboard codes to numeric values; returns undefined for non-digit keys.
buildCov(rot: quat, scale: vec3)
Returns the upper triangular elements [m00, m01, m02, m11, m12, m22] of Σ = R S Sᵀ Rᵀ, matching the layout expected by WGSL shaders.
sigmoid(x: number)
Numerically stable sigmoid implementation that avoids overflow for large |x|.
shNumCoefficients(l: number) / shDegreeFromNumCoeffs(n: number)
Utility pair for converting between SH degree and coefficient count. Returns undefined if n is not a perfect square.
Debugging & Profiling
class GPUStopwatch
Timestamp-query based profiler.
const stopwatch = new GPUStopwatch(device, 32);
stopwatch.start(encoder, 'gaussian-pass');
// ...
stopwatch.stop(encoder, 'gaussian-pass');
stopwatch.end(encoder);
const timings = await stopwatch.takeMeasurements(device.queue);
console.log(`${timings['gaussian-pass'] / 1e6} ms`);
start/stopaccept string labels and throw if labels repeat or exceed capacity.endresolves all queries into the internal buffer.takeMeasurementsmaps the query buffer, converts ticks to nanoseconds (usingqueue.getTimestampPeriod()when available), clears internal state, and returns{ [label]: durationNS }.
Buffer Debug Helpers (debug-gpu-buffers.ts)
| Function | Description |
|---|---|
readGPUBuffer(device, buffer, offset?, size?) |
Generic readback helper returning an ArrayBuffer. |
readU32FromBuffer(device, buffer, offset?) |
Convenience wrapper that interprets the readback as a single u32. |
readONNXCountBuffer(device, countBuffer) |
Reads dynamic point counts produced by ONNX inference. |
readModelParamsNumPoints(device, modelParamsBuffer) |
Reads the num_points uniform at byte offset 68. |
compareBufferValues(device, buffer1, offset1, buffer2, offset2, label) |
Logs and returns whether two u32 values match. |
debugCountPipeline(device, countBuffer, modelParamsBuffer, maxPoints) |
High-level trace that prints ONNX count, shader uniform count, and detects fallbacks to maxPoints. |
createShaderDebugBuffer(device, size?) |
Allocates a STORAGE |
readShaderDebugBuffer(device, buffer, numValues?) |
Reads the debug buffer back as Uint32Array and logs the values. |
All helpers wait for queue.onSubmittedWorkDone() before mapping buffers and destroy intermediate staging buffers automatically.
Float16 & SH Packing
f32_to_f16(val: number, opts?: F16Opts)
Converts a JS number (float32) into a binary16 value in [0, 65535].
Options (F16Opts):
- round: 'rne' (default) or 'rtz'
- ftz: flush half subnormals to 0
- saturate: clamp overflow to 0x7BFF instead of ±Inf
- canonicalNaN: force NaNs to 0x7E00
- emulateLegacyExpCutoff: zero results when exp < cutoff, matching legacy datasets
f16_to_f32(h: number)
Converts a binary16 payload back to float32 (returned as JS number).
packF16Array(src: Float32Array, opts?: F16Opts) / unpackF16Array(src: Uint16Array)
Batch conversions that respect the same options as f32_to_f16.
makeCopySH_PackedF16(params)
Creates an SH packer tailored to the source dataset:
const { copySH, wordsPerPoint } = makeCopySH_PackedF16({
props, // property names, e.g. ['x','y','z','f_dc_0',...]
iDC0, iDC1, iDC2,// indices of DC coefficients
k: 0 | 1 | 2 | 3,// SH degree
shU32 // destination Uint32Array
});
copySH(pointIndex * wordsPerPoint, rowValues);
- Writes exactly 48 half values (24
u32) per point, padding with zeros when necessary. - Reorders channel-first
f_rest_*fields into[R0,G0,B0, R1,G1,B1, …]to match WGSL expectations. - Returns
wordsPerPoint = 24so callers can advance the destination pointer without recomputing strides.
Mathematical Utilities
Camera Math (camera-math.ts)
deg2rad(d: number)focal2fov(focal: number, pixels: number)fov2focal(fov: number, pixels: number)
Example:
const verticalFov = focal2fov(800, canvas.height);
const focalLen = fov2focal(verticalFov, canvas.height);
Bounding Boxes (aabb.ts)
const bbox = new Aabb(vec3.fromValues(-1,-1,-1), vec3.fromValues(1,1,1));
bbox.center(); // vec3
bbox.radius(); // number
Internally Aabb clones the provided vectors, so mutating the inputs later does not affect the stored bounds.
Geometry Helpers
Vec3 Helpers (vector-math.ts)
| Function | Signature |
|---|---|
dot(a, b) |
Dot product |
add(a, b) / sub(a, b) |
Component-wise addition/subtraction |
scale(a, s) |
Scalar multiply |
len(a) |
Vector length |
normalize(a) |
Returns normalized vector or [NaN,NaN,NaN] if length is zero |
isFiniteVec3(a) |
Validity guard |
planeFromPoints(points: Vec3[], forceUp = true)
Fits a plane via covariance + power iteration. Returns { centroid, normal? }. When forceUp is true, the resulting normal is flipped upward if needed.
const upPlane = planeFromPoints(sampledPoints);
if (upPlane.normal) {
console.log('Up vector:', upPlane.normal);
}
Transform Constants
VIEWPORT_Y_FLIP: mat4
A precomputed matrix that flips Y in clip space:
Kept as a singleton to avoid repeated allocations in render loops.
Renderer & Environment Helpers
EnvMapHelper
| Method | Description |
|---|---|
loadHDRTexture(url) |
Loads an HDR texture via RGBELoader and sets EquirectangularReflectionMapping. |
createPMREMEnvironmentMap(renderer, texture) |
Generates a PMREM texture for the provided renderer, handling backend/device readiness checks and disposing the generator after use. Returns null on failure. |
setupRendererToneMapping(renderer, refRenderer?, toneMapping?, exposure?) |
Copies tone-mapping settings from another renderer or applies the provided defaults (ACES + 0.8). |
updateRendererEnvironment(renderer, scene) |
Calls renderer.updateEnvironment(scene) when available. |
setupSceneEnvironment(scene, envMap, background) |
Assigns scene.environment and scene.background. |
All methods log warnings instead of throwing when running inside partially initialized build artifacts.
RendererInitHelper
Types
interface RendererInitOptions {
sourceRenderer?: THREE.WebGPURenderer | null;
originalTexture?: THREE.Texture | null;
width?: number;
height?: number;
pixelRatio?: number;
fallbackHdrUrl?: string;
}
interface RendererInitResult {
envMap: THREE.Texture | null;
background: THREE.Texture | null;
}
initializeRenderer(renderer, scene, options?): Promise<RendererInitResult>
One-stop initialization routine:
1. Copies clear color, tone mapping, color space, shadow, and lighting flags from sourceRenderer, or applies defaults.
2. Sets pixel ratio and size when width/height are provided.
3. Chooses an environment source:
- reuses the supplied originalTexture,
- clones existing scene.environment, or
- loads fallbackHdrUrl (defaults to /public/textures/hdr/daytime.hdr).
4. Builds a PMREM for the target renderer and updates the scene/renderer references.
Returns { envMap, background } so callers can re-use the original HDR texture if needed.
isRendererInitialized(renderer: THREE.WebGPURenderer | null): boolean
Checks whether the renderer has a WebGPU backend and device before attempting GPU work.
Type Definitions
F16Opts
type F16Round = 'rne' | 'rtz';
interface F16Opts {
round?: F16Round;
ftz?: boolean;
saturate?: boolean;
canonicalNaN?: boolean;
emulateLegacyExpCutoff?: number;
}
Vec3
GenericGaussianPointCloudTS
Re-exported from the IO module for backward compatibility. Represents the generic interface returned by Gaussian loaders:
It exposes buffer accessors (gaussianBuffer, shCoefsBuffer), metadata (numPoints, shDegree, bbox), and optional hints (center, up, kernelSize, etc.).
These APIs can be imported from src/utils (or the project-specific alias) and are safe to use on both runtime and tooling paths.