Three.js WebGPU 渲染器原生高斯泼溅(Gaussian Splatting)支持
原作者:bhouston
原始 Link:Native Gaussian Splatting in Three.js for WebGPU Renderer
关联博客:Adding Native Gaussian Splatting Support to Three.js

1. 原文编译
原帖是 Three.js 论坛上的公告,作者 bhouston 宣布为 Three.js 的 WebGPU 渲染器添加了原生高斯泼溅支持。原文摘要如下:
Adding Native Gaussian Splatting Support to Three.js
How I added Gaussian Splatting to Three.js with WebGPU, TSL, a reusable GPU counting sort, SPZ v3/v4 and interoperability loaders, and SH1-SH3 view-dependent color.
可译为:
为 Three.js 添加原生高斯泼溅支持
我如何利用 WebGPU、TSL、可复用的 GPU 计数排序、SPZ v3/v4 与互操作加载器,以及 SH1-SH3 视角相关颜色,为 Three.js 添加高斯泼溅支持。
从摘要可以看出,该实现的核心不是简单的点云绘制,而是将 3D Gaussian Splatting(3DGS) 的关键计算链路搬到 GPU 端,并通过压缩格式与球谐函数分级来平衡性能与画质。

2. 核心代码
原帖为公告性质,未直接包含完整着色器代码。下面根据其关联实现给出核心接入代码,以及 GPU 排序的示意逻辑。
2.1 使用端核心代码
import { WebGPURenderer, Scene, PerspectiveCamera } from "three";
import { GaussianSplatNode } from "three/examples/jsm/objects/GaussianSplatNode.js";
import { SPZSplatLoader } from "three/examples/jsm/loaders/SPZSplatLoader.js";
const renderer = new WebGPURenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
const scene = new Scene();
const camera = new PerspectiveCamera(50, innerWidth / innerHeight, 0.1, 100);
camera.position.set(0, 0.5, 3);
// 加载 SPZ 压缩格式的高斯泼溅数据
const loader = new SPZSplatLoader();
const splatSource = await loader.loadAsync("lion.spz");
// 创建原生 Gaussian Splatting 节点
const splatNode = new GaussianSplatNode(splatSource);
splatNode.scale.setScalar(0.5);
scene.add(splatNode);
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
2.2 GPU 排序核心逻辑(概念性 TSL 伪代码)
// 1. 为每个 splat 生成深度键
// 通常使用视空间下的深度或距离平方作为排序键
const depthKey = dot(viewPosition, viewPosition);
// 2. 使用可复用 GPU counting sort 对 splat 索引进行排序
// 内部基于并行前缀和(prefix sum)与基数排序(radix sort)
const sortedSplatIndices = gpuCountingSort(depthKeys, splatCount);
// 3. 按排序结果进行 front-to-back 渲染
// 结合 SH1-SH3 视角相关颜色,输出最终 splat 颜色
说明:上述第二段为概念示意,实际实现封装在 Three.js 的 TSL 节点材质与 WebGPU compute shader 中。

3. 三个核心优化要点
优化 1:GPU 计数排序替代 CPU 排序
高斯泼溅渲染通常需要对大量 splat 做视空间深度排序。传统做法容易在 CPU 端产生回读和排序瓶颈。
该实现使用 可复用 GPU counting sort,配合并行前缀和,将排序任务留在 GPU 端,显著降低 CPU 压力,适合数十万甚至百万级 splat 的实时渲染。
优化 2:SPZ v3/v4 压缩格式与互操作加载器
直接加载 PLY 或原始高斯数据会占用大量内存和带宽。
引入 SPZ v3/v4 压缩格式后,可以大幅降低显存占用和加载时间;同时通过互操作加载器兼容不同工具导出的数据格式,提升工作流灵活性。
优化 3:SH1-SH3 视角相关颜色分级
视角相关颜色是 3DGS 的重要特性,但高阶球谐函数会增加 ALU 计算量和填充率压力。
该实现支持 SH1-SH3 多级球谐函数,允许开发者根据质量需求和设备性能选择不同阶数:SH1 开销低,SH3 能保留更丰富的高光与视角细节。

4. GLSL/WebGL 专业术语检查
| 原文术语 | 建议中文 | 检查说明 |
|---|---|---|
| WebGPU Renderer | WebGPU 渲染器 | 不要与 WebGL 混淆。WebGPU 使用 WGSL 作为底层着色语言,而非 GLSL。 |
| TSL | Three.js Shading Language | Three.js 的节点化着色语言,是对底层 GLSL/WGSL 的抽象层。TSL 可编译为 WebGL/GLSL 或 WebGPU/WGSL。 |
| GPU counting sort | GPU 计数排序 | 不是“ GPU 普通排序”。它是基于计数排序/基数排序 + 前缀和的并行算法。 |
| SPZ v3/v4 | SPZ v3/v4 压缩格式 | 一种面向高斯泼溅的压缩格式,注意版本差异带来的加载兼容性。 |
| SH1-SH3 | 球谐函数 1~3 阶 | 球谐函数阶数,用于表示视角相关颜色。SH3 比 SH1 更精细,但计算量更大。 |
| view-dependent color | 视角相关颜色 | 不推荐译为“视图依赖颜色”,更准确的表达是“随视角变化的颜色”。 |
| splat / splatting | 泼溅 / 高斯泼溅 | 在 3DGS 语境中通常保留英文或译为“泼溅”,不建议强行译为“飞溅”。 |
5. 小结
bhouston 的实现把高斯泼溅的关键瓶颈——排序、数据压缩与视角相关颜色——分别用 GPU counting sort、SPZ v3/v4 和 SH1-SH3 分级球谐函数 解决,并基于 Three.js TSL 在 WebGPU 渲染器中原生落地。这种“GPU 排序 + 压缩格式 + 分层球谐”的组合,是 WebGPU 渲染器支持 3DGS 的高性能路线之一。
