Three.js WebGPU 渲染器原生高斯泼溅(Gaussian Splatting)支持

原作者:bhouston
原始 Link:Native Gaussian Splatting in Three.js for WebGPU Renderer
关联博客:Adding Native Gaussian Splatting Support to Three.js


Native Gaussian Splatting in Three.js for WebGPU Renderer

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 端,并通过压缩格式与球谐函数分级来平衡性能与画质。


Screenshot 2026-08-12 at 11.33.14 AM

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 中。


lion-view-dependent-comparison

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 能保留更丰富的高光与视角细节。


Screenshot 2026-08-12 at 11.30.10 AM

4. GLSL/WebGL 专业术语检查

原文术语建议中文检查说明
WebGPU RendererWebGPU 渲染器不要与 WebGL 混淆。WebGPU 使用 WGSL 作为底层着色语言,而非 GLSL。
TSLThree.js Shading LanguageThree.js 的节点化着色语言,是对底层 GLSL/WGSL 的抽象层。TSL 可编译为 WebGL/GLSL 或 WebGPU/WGSL。
GPU counting sortGPU 计数排序不是“ GPU 普通排序”。它是基于计数排序/基数排序 + 前缀和的并行算法。
SPZ v3/v4SPZ 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 的高性能路线之一。