跳转至

Shaders模块

src/shaders/ 包含驱动 Visionary 管线的每个 WGSL 程序。TypeScript 层仅导入原始着色器字符串 (preprocess.wgsl, radix_sort.wgsl, gaussian.wgsl 以及实用内核)。本 README 解释了每个着色器的作用、它们如何交互以及覆盖/实时常量来自何处。

文件概览

文件 阶段 描述
preprocess.wgsl Compute 将 3D 高斯投影到屏幕空间 Splat,评估 SH/原始颜色,写入深度键 + 负载。包含用于原始颜色 (USE_RAW_COLOR)、SH 布局 (SH_LAYOUT_CHANNEL_MAJOR) 和压缩/int8/f16 数据的覆盖。
gaussian.wgsl Render (VS/FS) 消费排序后的 2D Splat,为每个实例构建四边形,评估高斯衰减,输出预乘颜色。
radix_sort.wgsl Compute 4-Pass GPU 基数排序 (直方图 + 前缀 + 散列),支持乒乓缓冲和间接调度。工作组大小等常量由 TypeScript 注入。
compress_gaussians.wgsl Compute 工具使用的可选内核,用于将 FP32 Splat 转换为量化格式 (int8/f16)。与预处理共享结构体布局。
convert_precision.wgsl Compute ONNX 转换路径使用的运行时精度交换 (FP32 → FP16/INT8)。
debug-helpers.wgsl Compute 用于 GPU 端调试的小型实用程序(例如,复制计数器、转储缓冲)。
index.ts TS glue 通过 Vite 的 ?raw 加载器重新导出原始着色器字符串。

管线概览

3D Gaussians
  │  ├─ preprocess.wgsl  (相机 → Splat + 深度 + 排序计数器)
  │  ├─ radix_sort.wgsl  (深度排序 + 间接调度)
  │  ├─ gaussian.wgsl    (渲染排序后的 Splat → 颜色缓冲)
  │  └─ display / compositor (在渲染器中处理;环境贴图着色器位于核心之外)
  • Preprocess 通过 uModel.gaussDataType 读取打包的高斯数据 (FP32/FP16/INT8),应用相机矩阵,将协方差转换为屏幕空间椭圆,评估球谐函数或原始 RGB (USE_RAW_COLOR = true),并写入全局 Splat 缓冲以及排序器键/负载缓冲。它还为间接排序/绘制递增原子计数器。
  • Radix sort 读取深度键/负载,运行直方图/前缀/散列 Pass(使用乒乓键/负载缓冲),并留下 gaussian.wgsl 用作索引缓冲的排序负载列表。工作组大小/基数配置是注入的字符串(参见渲染器设置)。
  • Gaussian 是一个极简的实例化渲染管线:顶点着色器获取特征向量 + 中心点 + 颜色,为每个实例生成四个顶点,片元着色器在计算 exp(-r²) 并返回预乘 RGBA 之前,会裁剪 dot(screen_pos, screen_pos) > 2*CUTOFF 的样本。

覆盖与特化常量

  • MAX_SH_DEG – 在着色器编译之前由渲染器注入,以限制 SH 评估成本。
  • USE_RAW_COLOR – 对于颜色模式模型(例如带有 RGB 的 DynamicPointCloud)设置为 true。为 true 时,预处理跳过 SH 评估并直接解释 color_buffer 负载。
  • SH_LAYOUT_CHANNEL_MAJOR – 在旧版“交错”SH 存储(每个系数 RGB 三元组)和较新的通道优先布局 (Rdc,Gdc,Bdc,R₁,R₂...G₁...G₂...B₁...Bₘ) 之间切换。这与加载器/ONNX 路径匹配。
  • DISCARD_BY_WORLD_TRACE/MAX_WORLD_TRACE – 可选保护,用于丢弃世界空间协方差迹超过阈值的 Splat(用于调试不良资产)。
  • 基数排序常量 (histogram_wg_size, histogram_sg_size 等) 由 GPURSSorter.processShaderTemplate 生成,以匹配 WebGPU 设备。

数据契约

预处理输出 (Splat)

struct Splat {
  v_0: u32; v_1: u32; // 打包的特征向量 (4×f16)
  pos: u32;           // 打包的 NDC x/y (2×f16)
  posz: f32;          // 未打包的 NDC z (f32 精度)
  color_0: u32; color_1: u32; // 打包的 RGBA (4×f16)
}
每个 Splat 占用 32 字节(匹配 BUFFER_CONFIG.SPLAT_STRIDE)。gaussian.wgsl 逐字读取这些结构体。

排序元数据

struct SortInfos {
  keys_size : atomic<u32>;  // 本帧写入了多少 Splat
  padded_size : u32;        // 容量 (工作组块的倍数)
  passes : u32;
  even_pass : u32;
  odd_pass : u32;
}
struct DrawIndirect {
  vertex_count   : u32;      // 始终为 4
  instance_count : atomic<u32>;
  base_vertex    : u32;
  base_instance  : u32;
}
struct DispatchIndirect {
  dispatch_x : atomic<u32>;
  dispatch_y : u32;
  dispatch_z : u32;
}
预处理写入 keys_size/instance_count/dispatch_x,基数排序通过间接调度消费它们,渲染器在发出 drawIndirect 之前将 keys_size 复制到间接绘制缓冲中。

相关代码

  • Renderer (src/renderer/gaussian_renderer.ts) 注入 MAX_SH_DEG,选择原始 vs SH 颜色模式,并绑定着色器布局。
  • Preprocessor TS (GaussianPreprocessor) 在运行时替换存储缓冲(例如,在精度转换后)并转发 ModelParams Uniform 的 uModel 值。
  • Sorter TS (GPURSSorter) 注入基数常量并协调直方图/前缀/散列 Pass。

有关更深入的绑定图、布局细节和每个入口点的文档,请参阅 架构API 参考

相关文档