如何使用Three.js的新原生Gaussian Splats

Hacker News Top 工具

摘要

本文提供了一个关于使用Three.js原生Gaussian Splatting支持的实用指南,解释了如何在Web 3D场景中加载和渲染Gaussian Splats,并附有代码示例。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/09/13 11:36

# 如何使用 Three.js 的原生高斯溅射 来源:https://ben3d.ca/blog/how-to-use-threejs-native-gaussian-splats 最新发布的 Three.js r186 版本新增了原生的 3D 高斯溅射 (https://en.wikipedia.org/wiki/Gaussian_splatting) 支持,这意义重大:此前在 Three.js 中虽可通过社区插件实现溅射效果,但如今它已成为引擎的一等公民,内置了相应的网格类型和主流格式的加载器。 我在早期的文章《为 Three.js 添加原生高斯溅射支持》(https://ben3d.ca/blog/gaussian-splatting-for-threejs) 中介绍了相关的底层技术细节。本文则是其实用的配套指南:高斯溅射适用于何种场景,如何通过几行代码加载和渲染一个溅射,如何选择文件格式,以及如何从现实世界的捕捉生成可直接放入 Three.js 场景的溅射。 ## 高斯溅射 高斯溅射是一种点云,其中每个点是一个模糊的、有方向的、带颜色的三维椭球体(即一个“溅射”),而非坚硬的顶点。渲染成千上万乃至数百万个这样的溅射,将它们从后往前排序混合,就能形成逼真的图像,无需传统表面重建所需的网格化、UV 展开或材质烘焙工作。 这使得溅射非常适合捕捉现实世界的物体和场景,并以高保真度进行展示,尤其是那些难以手动建模的主体:植被、毛发、反光或半透明表面、杂乱的房间、博物馆文物。因为溅射是直接由照片构建而成,而非手工制作的网格,所以其结果看起来就像原始素材,却只需传统重建工作的一小部分。一旦加载,你可以像对待 Three.js 场景中的任何其他对象一样处理它:每一帧都重新进行排序和着色。 在 Three.js 中渲染的西红柿高斯溅射 不过,有一个规模限制需要提前知晓:`GaussianSplat` 是为单个捕捉对象或房间尺度场景设计的,并非整个城市街区。它不具备细节层次(LOD)流式传输、空间分块或剔除功能,因此城市级别的捕捉或数 GB 的溅射点云在流畅运行前,需要手动进行分块或简化处理。基于此基础的更大场景工具可以后续构建,我在实施文章 (https://ben3d.ca/blog/gaussian-splatting-for-threejs) 中对此基础工作进行了探讨。 ## 加载 SPZ 文件 以下是完整的流程,从开始到结束:加载一个 `.spz` 文件,将其包装为一个网格,并渲染它。 ``` import * as THREE from 'three/webgpu'; import { SPZLoader } from 'three/addons/loaders/SPZLoader.js'; import { GaussianSplat } from 'three/addons/objects/GaussianSplat.js'; const renderer = new THREE.WebGPURenderer(); await renderer.init(); const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera( 50, window.innerWidth / window.innerHeight, 0.01, 100 ); camera.position.set( 0, 0.3, 2 ); // 1. 加载溅射数据 const splatGeometry = await new SPZLoader().loadAsync( 'model.spz' ); // 2. 将其包装为网格并添加到场景中 const splats = new GaussianSplat( splatGeometry ); scene.add( splats ); // 3. 像往常一样渲染。网格默认会在每帧自动排序。 renderer.setAnimationLoop( () => { renderer.render( scene, camera ); } ); ``` 实际上,操作就是这么简单:一次加载调用,一个 `new GaussianSplat( geometry )`,以及一次 `scene.add()`。因为 `GaussianSplat` 继承自 `THREE.Mesh`,所以它能像其他任何对象一样与场景图的其余部分组合,变换、`visible` 属性和射线投射组都如你预期般工作。 需要牢记的一个要求是:`GaussianSplat` 需要 `WebGPURenderer`。该渲染器由 TSL 节点加上用于深度排序的计算着色器构建而成,因此请确保你的导入映射中能解析到 `three/webgpu` 和 `three/tsl`。 ## 选择文件格式 溅射有多种文件格式,具体取决于它们被捕捉或导出的方式。Three.js 提供了五种加载器来覆盖这些格式。所有五种加载器都生成相同的内部 `BufferGeometry` 形状(`position`、`covariance`、`color`,以及可选的打包 `sphericalHarmonics1..3` 属性),因此无论你使用哪种加载器,`GaussianSplat` 对结果的处理都是一致的: 加载器 | 扩展名 | 备注 ---|---|--- `SPZLoader` | `.spz` | **推荐。** Niantic 的紧凑格式。v4 版本采用 zstd 压缩,并按部分流式传输:文件最小,加载最快。也读取旧版 v1–v3(gzip)。 `GaussianSplatPLYLoader` | `.ply` | **互操作性最强。** 原始 3D Gaussian Splatting 研究代码及大多数训练/清理工具的原生输出格式,因此这是你最常收到的格式。未压缩,按顶点存储文本/二进制数据,磁盘占用大,加载速度相比 `.spz` 较慢。 `KSPLATLoader` | `.ksplat` | `GaussianSplats3D` 查看器使用的格式。如果你已有来自该流程的资产,则很有用。 `SPLATLoader` | `.splat` | 原始的固定 32 字节每溅射格式(antimatter15/splat)。未压缩,易于生成,磁盘占用大。 `GLTFGaussianSplatLoaderExtension` | `.gltf` / `.glb` | 实现了 `KHR_gaussian_splatting` (https://www.khronos.org/news/press/gltf-gaussian-splatting-press-release) glTF 扩展,因此溅射可以作为普通 glTF 资产的一部分,与网格、相机和动画一起传输。 如果可以选择格式,请在查看器中使用 SPZ 版本 4:它提供最小的传输尺寸和最快的解析速度。 ### 加载 PLY 溅射 溅射也常以 `.ply` 文件形式提供,因为这是原始 3D Gaussian Splatting 研究代码及许多训练和清理工具的原生输出格式。`GaussianSplatPLYLoader` 可以处理它们,遵循与 `SPZLoader` 和 `SPLATLoader` 相同的模式: ``` import { GaussianSplatPLYLoader } from 'three/addons/loaders/GaussianSplatPLYLoader.js'; import { GaussianSplat } from 'three/addons/objects/GaussianSplat.js'; const splatGeometry = await new GaussianSplatPLYLoader().loadAsync( 'point_cloud.ply' ); scene.add( new GaussianSplat( splatGeometry ) ); ``` 当溅射仅以原始 `.ply` 导出形式存在时,这是应该使用的加载器。 ### 加载 glTF 溅射 如果你的溅射嵌入在 glTF 文件中,有一个额外的设置步骤。因为 `GaussianSplat` 需要 `WebGPURenderer`,`GLTFLoader` 不会自动为你注册 glTF 溅射插件,所以你需要自己注册: ``` import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js'; import { GLTFGaussianSplatLoaderExtension } from 'three/addons/loaders/GLTFGaussianSplatLoaderExtension.js'; const loader = new GLTFLoader(); loader.register( ( parser ) => new GLTFGaussianSplatLoaderExtension( parser ) ); const gltf = await loader.loadAsync( 'scene.gltf' ); scene.add( gltf.scene ); // 溅射图元作为 GaussianSplat 实例加载 ``` 注册后,使用 `KHR_gaussian_splatting` 的网格图元会加载为 `GaussianSplat`(或对于多图元网格,加载为一个 `Group`),并像任何其他 glTF 节点一样放入返回的场景图中,如果文件中包含,则会与普通网格、相机和动画混合在一起。 ### 加载 SPLAT 和 KSPLAT 文件(遗留格式) `SPLATLoader` 和 `KSPLATLoader` 主要用于遗留兼容性,涵盖围绕 `antimatter15/splat` 和 `GaussianSplats3D` 查看器构建的资产和流程。 其 API 与 `SPZLoader` 非常接近,因此在它们之间切换只需选择正确的加载器类并指向相应的扩展名: ``` import { SPLATLoader } from 'three/addons/loaders/SPLATLoader.js'; import { GaussianSplat } from 'three/addons/objects/GaussianSplat.js'; const splatGeometry = await new SPLATLoader().loadAsync( 'model.splat' ); scene.add( new GaussianSplat( splatGeometry ) ); ``` ``` import { KSPLATLoader } from 'three/addons/loaders/KSPLATLoader.js'; import { GaussianSplat } from 'three/addons/objects/GaussianSplat.js'; const splatGeometry = await new KSPLATLoader().loadAsync( 'model.ksplat' ); scene.add( new GaussianSplat( splatGeometry ) ); ``` 两种加载器都生成与 `SPZLoader` 相同的 `BufferGeometry` 形状,因此 `GaussianSplat` 及其所有下游处理(排序、渲染、glTF 导出)的行为,无论你使用哪种加载器获取数据,都是一致的。 ## 捕捉、清理、转换、渲染 将现实世界的主体转化为你 Three.js 场景中的溅射,需要四个步骤。 ### 1. 捕捉 首先,使用移动扫描应用围绕你的主体走动。重叠的照片或视频会发送到应用(或其云后端),应用会从中重建一个溅射。有几个应用在这方面做得很好: - **Polycam (https://poly.cam/)**:在移动应用中进行高斯溅射捕捉,云端处理。 - **Scaniverse (https://scaniverse.com/)**:Niantic 的移动扫描应用,支持设备端高斯溅射捕捉,并可直接导出为 `.spz`。 - **Luma AI (https://lumalabs.ai/)**:消费者级的溅射捕捉应用,云端处理。 这三个中的任何一个都能从你的捕捉中重建出一个可用的溅射。 ### 2. 清理 原始重建结果往往带有多余的漂浮溅射、背景杂物和粗糙边缘,因此在发布前值得修剪它们。 - **Polycam (https://poly.cam/)** 有其自身的裁剪和清理工具,如果你用它进行捕捉并希望留在同一个应用中,这很方便。 - **SuperSplat (https://superspl.at/)**(PlayCanvas 的免费在线编辑器)是专为溅射编辑而设计的:裁剪、擦除漂浮物、重新导出。它适用于来自任何来源的溅射,因此当你想要比捕捉应用提供的更多控制,或者溅射来自其他地方时,可以使用它。 ### 3. 转换为 SPZ 一旦你有了一个干净的溅射(通常是 `.ply` 或 `.splat` 格式),在加载到 Three.js 之前将其转换为 `.spz` v4: - **Niantic 的在线 SPZ 转换器 (https://scaniverse.com/spz)**:上传 `.ply`/`.splat`,下载 `.spz`。 - 如果你是使用 **Scaniverse** 进行捕捉,可以完全跳过此步骤,因为它直接导出 `.spz` v4。 ### 4. 渲染 现在你有了 `.spz` 文件,将其放入项目中,并使用 `SPZLoader` 和 `GaussianSplat` 加载它,具体方式与本文前面的示例完全一致。

相似文章

周末掌握3D Gaussian Splatting

Hacker News Top

一篇使用C++和OpenGL从零构建简化版3D Gaussian Splatting渲染器的教程,涵盖加载和渲染Gaussian splats。

GlobalSplat: 通过全局场景标记实现高效的前馈式三维高斯散射

Hugging Face Daily Papers

GlobalSplat 引入了一种高效的前馈框架,用于三维高斯散射,通过全局场景标记实现紧凑且一致的场景重建,将计算开销和推理时间降低至78毫秒以下。该方法采用从粗到细的训练策略,防止表示膨胀,同时以显著更少的高斯原语(16K)达到有竞争力的新视角合成性能,与密集基线相比更为高效。

Tsplat – 在终端中运行高斯泼溅渲染

Hacker News Top

Tsplat 是一款基于 Rust 的命令行工具,仅使用 CPU 即可直接在终端中渲染 3D 高斯泼溅场景,甚至支持通过 SSH 运行。它支持 Unicode 半角块和图形协议,并具有导航和自动旋转控制。

在Julia中实现更好的高斯溅射

Hacker News Top

GaussianSplatting.jl 2.0版本通过KernelAbstractions.jl带来了多GPU后端支持、多线程UI、MCMC致密化策略,以及用于更好3D重建的深度/几何监督。