Utils模块 API 参考
本参考文档涵盖了 src/utils/ 暴露的每个公共辅助函数,按功能分组。
目录
- GPU 实用工具 (GPU Utilities)
- 调试与性能分析 (Debugging & Profiling)
- Float16 与 SH 打包 (Float16 & SH Packing)
- 数学实用工具 (Mathematical Utilities)
- 几何辅助工具 (Geometry Helpers)
- 变换常量 (Transform Constants)
- 渲染器与环境辅助工具 (Renderer & Environment Helpers)
- 类型定义 (Type Definitions)
GPU 实用工具 (GPU Utilities)
align4(n: number): number
将 n 按位对齐到下一个 4 字节边界。WebGPU 缓冲复制所必需。
align8(n: number): number
将 n 按位对齐到下一个 8 字节边界。缓冲映射所必需。
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? }。当 forceUp 为 true 时,如果需要,结果法线将向上翻转。
const upPlane = planeFromPoints(sampledPoints);
if (upPlane.normal) {
console.log('Up vector:', upPlane.normal);
}
变换常量 (Transform Constants)
VIEWPORT_Y_FLIP: mat4
一个预计算的矩阵,用于在裁剪空间中翻转 Y:
作为单例保留,以避免在渲染循环中重复分配。
渲染器与环境辅助工具 (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.environment 和 scene.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
GenericGaussianPointCloudTS
从 IO Module 重新导出以实现向后兼容性。表示由高斯加载器返回的通用接口:
它暴露缓冲访问器 (gaussianBuffer, shCoefsBuffer)、元数据 (numPoints, shDegree, bbox) 和可选提示 (center, up, kernelSize 等)。
这些 API 可以从 src/utils(或项目特定的别名)导入,并且可以在运行时和工具路径上安全使用。