Renderer API 参考
本文档涵盖了 src/renderer/ 的公开接口。它跟踪实际的 TypeScript 导出,以便集成者可以配置、驱动和检查 GaussianRenderer。
导出项 (Exports)
import {
GaussianRenderer,
DEFAULT_KERNEL_SIZE,
type RendererConfig,
type RenderArgs,
type RenderStats,
type IRenderer,
} from 'src/renderer';
接口 (Interfaces)
RenderArgs
interface RenderArgs {
camera: PerspectiveCamera; // 必须提供的视图/投影提供者
viewport: [number, number]; // 画布宽度/高度(像素)
clippingBox?: { min: vec3; max: vec3 };
maxSHDegree?: number;
showEnvMap?: boolean;
mipSplatting?: boolean;
kernelSize?: number;
walltime?: number;
sceneExtend?: number;
sceneCenter?: vec3;
}
在每次调用 dispatchModel 之前,这些值会在 buildRenderSettings() 内部与每个点云的元数据合并。任何省略的字段都将回退到 PointCloud 的默认值(bbox、中心点、PointCloud.kernelSize 等)。
RendererConfig
interface RendererConfig {
device: GPUDevice;
format: GPUTextureFormat; // 交换链 / 渲染目标格式
shDegree: number; // 此渲染器支持的最大 SH 阶数
compressed?: boolean; // 为未来的压缩数据路径保留
debug?: boolean; // 启用详细日志记录和全局句柄
}
旧版的构造函数 (device, format, shDeg, compressed?) 仍然受支持,但推荐使用配置对象。
RenderStats
interface RenderStats {
gaussianCount: number; // pointCloud.numPoints
visibleSplats: number; // 最新的排序器 keys_size / 缓存的 num_points
memoryUsage: number; // 粗略估计值(splat + 排序器缓冲)
}
IRenderer
interface IRenderer {
initialize(): Promise<void>;
prepareMulti(
encoder: GPUCommandEncoder,
queue: GPUQueue,
pointClouds: PointCloud[],
args: RenderArgs,
): void;
render(pass: GPURenderPassEncoder, pointCloud: PointCloud): void;
renderMulti(pass: GPURenderPassEncoder, pointClouds: PointCloud[]): void;
getPipelineInfo(): { format: GPUTextureFormat; bindGroupLayouts: GPUBindGroupLayout[] };
}
GaussianRenderer 实现了此接口,并添加了一些如下所述的便捷/调试辅助方法。
GaussianRenderer 类
构造函数
new GaussianRenderer({ device, format, shDegree, compressed?, debug? }: RendererConfig)
new GaussianRenderer(device: GPUDevice, format: GPUTextureFormat, shDegree: number, compressed?: boolean)
两种形式是等价的;配置对象版本支持未来的选项而不破坏调用点。
生命周期
initialize(): Promise<void>– 创建排序器、双预处理器、管线布局、渲染/深度管线、间接绘制缓冲以及初始的 100 万 Splat 全局缓冲。ensureSorter(): Promise<void>– 旧版别名,如果需要,仅调用initialize()。
帧入口点
prepareMulti(encoder, queue, pointClouds, args)- 确保全局容量 –
pointCloud.numPoints的总和(1.25 倍增长因子)。 - 重置排序器的间接缓冲和
keys_size。 - 对于每个点云:选择 SH 或 RGB 预处理器,使用
baseOffset+ 可选的 ONNXcountBuffer调用dispatchModel。 - 运行单次
sorter.recordSortIndirect(...)并将可见 Splat 计数复制到间接绘制缓冲中。 render(pass, pointCloud)- 使用每个云缓存的排序资源 (
WeakMap)。 - 在
@group(0)绑定pointCloud.renderBindGroup(),在@group(1)绑定缓存的排序器渲染绑定组。 - 使用共享的间接缓冲发出一次
drawIndirect。 renderMulti(pass, pointClouds)- 要求事先调用
prepareMulti。 - 绑定全局
renderBG(全局 splat 缓冲)和全局排序器渲染绑定组,然后调用一次drawIndirect。
管线控制
getPipelineInfo()– 返回{ format, bindGroupLayouts: [PointCloud.renderBindGroupLayout(device), GPURSSorter.createRenderBindGroupLayout(device)] }供外部渲染通道使用。setDepthEnabled(enabled: boolean)– 切换后续绘制中是否使用深度感知管线变体。setDepthFormat(format: GPUTextureFormat)– 默认更新depth24plus;重新创建深度管线以匹配新的附件格式。
诊断与统计
getRenderStats(pointCloud)– 包装RenderStats用于 UI 叠加层或日志记录。readInstanceCountDebug()– GPU→CPU 回读当前的间接实例计数。readPayloadSampleDebug(n = 8)– 从全局排序器缓冲转储前n个负载索引(需要prepareMulti/ 全局缓冲)。debugONNXCount()– 当 ONNX 驱动的计数处于活动状态时,挂钩到预处理器的调试例程。
实用工具
DEFAULT_KERNEL_SIZE– 导出的常量 (0.3),当未提供RenderArgs.kernelSize和PointCloud.kernelSize时使用。
使用模式
多模型帧
const renderer = new GaussianRenderer({ device, format, shDegree: 3 });
await renderer.initialize();
renderer.prepareMulti(encoder, device.queue, pointClouds, {
camera,
viewport: [canvas.width, canvas.height],
maxSHDegree: 3,
});
const pass = encoder.beginRenderPass(passDesc);
renderer.renderMulti(pass, pointClouds);
pass.end();
单模型渲染(旧路径)
旧路径指的是在引入多模型批处理(prepareMulti/renderMulti)之前使用的逐模型渲染方式。虽然现在仍然支持,但推荐使用批处理方式,即使是单个模型。
旧路径特点:
- 使用 render(pass, pointCloud) 方法,每个模型单独调用
- 使用每个点云自己的 splat2DBuffer(由 PointCloud 模块管理)
- 使用缓存的每云排序资源(WeakMap<PointCloud, PointCloudSortStuff>)
- 每个模型单独执行绘制调用
const pointCloud = loadPointCloud();
renderer.prepareMulti(encoder, device.queue, [pointCloud], args); // 仍然推荐
renderer.render(pass, pointCloud); // 使用每云缓存,单独绘制
注意:即使是单个模型,也推荐使用 renderMulti(),因为它使用全局缓冲区,性能更好。
深度管线切换
调试辅助
await renderer.readInstanceCountDebug();
await renderer.readPayloadSampleDebug(16);
await renderer.debugONNXCount();
注意事项
- 务必在
renderMulti之前调用prepareMulti;预处理会填充排序器缓冲和间接绘制计数。 - 如果仅渲染单个点云,缓存仍然有效,但容量管理可能会跳过全局缓冲,直到使用了
prepareMulti。 - 统计和调试实用程序会回读 GPU 缓冲;在生产版本中应谨慎使用。