跳转至

Utils模块 API 参考

本参考文档涵盖了 src/utils/ 暴露的每个公共辅助函数,按功能分组。

目录

  1. GPU 实用工具 (GPU Utilities)
  2. 调试与性能分析 (Debugging & Profiling)
  3. Float16 与 SH 打包 (Float16 & SH Packing)
  4. 数学实用工具 (Mathematical Utilities)
  5. 几何辅助工具 (Geometry Helpers)
  6. 变换常量 (Transform Constants)
  7. 渲染器与环境辅助工具 (Renderer & Environment Helpers)
  8. 类型定义 (Type Definitions)

GPU 实用工具 (GPU Utilities)

align4(n: number): number

n 按位对齐到下一个 4 字节边界。WebGPU 缓冲复制所必需。

align4(13); // → 16

align8(n: number): number

n 按位对齐到下一个 8 字节边界。缓冲映射所必需。

align8(18); // → 24

readWholeBuffer(device, src, byteLength, srcOffset = 0): Promise<Uint8Array>

src 读取 byteLength 字节到 CPU 内存。内部流程: 1. 通过 align4/align8 对复制/映射大小进行取整 2. 分配一个暂存缓冲 (COPY_DST | MAP_READ) 3. 复制数据并在支持的情况下等待 GPU 队列完成 4. 映射,切片请求的区域,并销毁暂存缓冲

如果 src 缺少 GPUBufferUsage.COPY_SRC,则抛出异常。

dumpU32(bytes: Uint8Array): void / dumpHex(bytes: Uint8Array): void

用于将回读数据可视化为 Uint32 值或十六进制字符串的日志辅助函数。

keyToNum(code: string): number | undefined

"Digit0""Digit9" 键盘代码映射为数值;对于非数字键返回 undefined

buildCov(rot: quat, scale: vec3)

返回 Σ = R S Sᵀ Rᵀ 的上三角元素 [m00, m01, m02, m11, m12, m22],与 WGSL 着色器期望的布局匹配。

sigmoid(x: number)

数值稳定的 sigmoid 实现,避免大 |x| 时的溢出。

shNumCoefficients(l: number) / shDegreeFromNumCoeffs(n: number)

用于在 SH 阶数和系数数量之间进行转换的工具对。如果 n 不是完全平方数,则返回 undefined


调试与性能分析 (Debugging & Profiling)

class GPUStopwatch

基于时间戳查询的分析器。

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 / stop 接受字符串标签,如果标签重复或超出容量则抛出异常。
  • end 将所有查询解析到内部缓冲。
  • takeMeasurements 映射查询缓冲,将刻度转换为纳秒(可用时使用 queue.getTimestampPeriod()),清除内部状态,并返回 { [label]: durationNS }

缓冲调试辅助工具 (debug-gpu-buffers.ts)

函数 描述
readGPUBuffer(device, buffer, offset?, size?) 通用回读辅助函数,返回 ArrayBuffer
readU32FromBuffer(device, buffer, offset?) 便捷包装器,将回读解释为单个 u32
readONNXCountBuffer(device, countBuffer) 读取由 ONNX 推理产生的动态点数。
readModelParamsNumPoints(device, modelParamsBuffer) 读取字节偏移量 68 处的 num_points uniform。
compareBufferValues(device, buffer1, offset1, buffer2, offset2, label) 记录并返回两个 u32 值是否匹配。
debugCountPipeline(device, countBuffer, modelParamsBuffer, maxPoints) 高级跟踪,打印 ONNX 计数、着色器 uniform 计数,并检测回退到 maxPoints 的情况。
createShaderDebugBuffer(device, size?) 分配一个 STORAGE
readShaderDebugBuffer(device, buffer, numValues?) 将调试缓冲回读为 Uint32Array 并记录值。

所有辅助函数在映射缓冲之前等待 queue.onSubmittedWorkDone(),并自动销毁中间暂存缓冲。


Float16 与 SH 打包 (Float16 & SH Packing)

f32_to_f16(val: number, opts?: F16Opts)

将 JS number (float32) 转换为 [0, 65535] 中的 binary16 值。

选项 (F16Opts): - round: 'rne' (默认) 或 'rtz' - ftz: 将半精度次正规数 (subnormals) 刷新为 0 - saturate: 溢出时钳位到 0x7BFF 而不是 ±Inf - canonicalNaN: 强制 NaN 为 0x7E00 - emulateLegacyExpCutoff: 当 exp < cutoff 时结果为零,以匹配遗留数据集

f16_to_f32(h: number)

将 binary16 负载转换回 float32(作为 JS number 返回)。

packF16Array(src: Float32Array, opts?: F16Opts) / unpackF16Array(src: Uint16Array)

批量转换,遵循与 f32_to_f16 相同的选项。

makeCopySH_PackedF16(params)

创建一个针对源数据集定制的 SH 打包器:

const { copySH, wordsPerPoint } = makeCopySH_PackedF16({
  props,           // 属性名称, 例如 ['x','y','z','f_dc_0',...]
  iDC0, iDC1, iDC2,// DC 系数的索引
  k: 0 | 1 | 2 | 3,// SH 阶数
  shU32            // 目标 Uint32Array
});

copySH(pointIndex * wordsPerPoint, rowValues);
  • 每个点精确写入 48 个半精度值(24 u32),必要时用零填充。
  • 将通道优先的 f_rest_* 字段重新排序为 [R0,G0,B0, R1,G1,B1, …] 以匹配 WGSL 预期。
  • 返回 wordsPerPoint = 24,以便调用者可以在不重新计算步幅的情况下推进目标指针。

数学实用工具 (Mathematical Utilities)

相机数学 (camera-math.ts)

  • deg2rad(d: number)
  • focal2fov(focal: number, pixels: number)
  • fov2focal(fov: number, pixels: number)

示例:

const verticalFov = focal2fov(800, canvas.height);
const focalLen = fov2focal(verticalFov, canvas.height);

包围盒 (aabb.ts)

const bbox = new Aabb(vec3.fromValues(-1,-1,-1), vec3.fromValues(1,1,1));
bbox.center(); // vec3
bbox.radius(); // number

Aabb 内部克隆提供的向量,因此稍后修改输入不会影响存储的边界。


几何辅助工具 (Geometry Helpers)

Vec3 辅助工具 (vector-math.ts)

函数 签名
dot(a, b) 点积
add(a, b) / sub(a, b) 分量加法/减法
scale(a, s) 标量乘法
len(a) 向量长度
normalize(a) 返回归一化向量,如果长度为零则返回 [NaN,NaN,NaN]
isFiniteVec3(a) 有效性守卫

planeFromPoints(points: Vec3[], forceUp = true)

通过协方差 + 幂迭代拟合平面。返回 { centroid, normal? }。当 forceUptrue 时,如果需要,结果法线将向上翻转。

const upPlane = planeFromPoints(sampledPoints);
if (upPlane.normal) {
  console.log('Up vector:', upPlane.normal);
}

变换常量 (Transform Constants)

VIEWPORT_Y_FLIP: mat4

一个预计算的矩阵,用于在裁剪空间中翻转 Y:

const flipped = mat4.create();
mat4.multiply(flipped, VIEWPORT_Y_FLIP, originalViewProj);

作为单例保留,以避免在渲染循环中重复分配。


渲染器与环境辅助工具 (Renderer & Environment Helpers)

EnvMapHelper

方法 描述
loadHDRTexture(url) 通过 RGBELoader 加载 HDR 纹理并设置 EquirectangularReflectionMapping
createPMREMEnvironmentMap(renderer, texture) 为提供的渲染器生成 PMREM 纹理,处理后端/设备就绪检查,并在使用后处置生成器。失败时返回 null
setupRendererToneMapping(renderer, refRenderer?, toneMapping?, exposure?) 从另一个渲染器复制色调映射设置或应用提供的默认值 (ACES + 0.8)。
updateRendererEnvironment(renderer, scene) 可用时调用 renderer.updateEnvironment(scene)
setupSceneEnvironment(scene, envMap, background) 分配 scene.environmentscene.background

所有方法在部分初始化的构建产物中运行时,会记录警告而不是抛出异常。

RendererInitHelper

类型

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>

一站式初始化例程: 1. 从 sourceRenderer 复制清除颜色、色调映射、颜色空间、阴影和光照标志,或应用默认值。 2. 当提供 width/height 时设置像素比和尺寸。 3. 选择环境源: - 重用提供的 originalTexture, - 克隆现有的 scene.environment,或 - 加载 fallbackHdrUrl(默认为 /public/textures/hdr/daytime.hdr)。 4. 为目标渲染器构建 PMREM 并更新场景/渲染器引用。

返回 { envMap, background } 以便调用者在需要时可以重用原始 HDR 纹理。

isRendererInitialized(renderer: THREE.WebGPURenderer | null): boolean

在尝试 GPU 工作之前检查渲染器是否具有 WebGPU 后端和设备。


类型定义 (Type Definitions)

F16Opts

type F16Round = 'rne' | 'rtz';
interface F16Opts {
  round?: F16Round;
  ftz?: boolean;
  saturate?: boolean;
  canonicalNaN?: boolean;
  emulateLegacyExpCutoff?: number;
}

Vec3

type Vec3 = [number, number, number];

GenericGaussianPointCloudTS

从 IO Module 重新导出以实现向后兼容性。表示由高斯加载器返回的通用接口:

type GenericGaussianPointCloudTS = import('../io').GaussianDataSource;

它暴露缓冲访问器 (gaussianBuffer, shCoefsBuffer)、元数据 (numPoints, shDegree, bbox) 和可选提示 (center, up, kernelSize 等)。


这些 API 可以从 src/utils(或项目特定的别名)导入,并且可以在运行时和工具路径上安全使用。