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)
}
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) 在运行时替换存储缓冲(例如,在精度转换后)并转发ModelParamsUniform 的uModel值。 - Sorter TS (
GPURSSorter) 注入基数常量并协调直方图/前缀/散列 Pass。
有关更深入的绑定图、布局细节和每个入口点的文档,请参阅 架构 和 API 参考。
相关文档
- 架构 (Architecture) – 着色器入口点图、特化常量和缓冲模式。
- API 参考 (API Reference) – 原始 WGSL 导出、覆盖表和 TS 胶水辅助函数。
- Preprocess Module – 展示如何从 TypeScript 调度
preprocess.wgsl。 - Sorting Module – 解释
radix_sort.wgsl如何连接到间接调度。 - Renderer Module – 记录
gaussian.wgsl如何被绑定和提供数据。