跳到正文
World Labs · 空间智能与世界模型· 一手来源·· 2026-04-14精选AI 评分66

在网页上流式传输 3DGS 世界

Streaming 3DGS worlds on the web

推荐理由

原文拆解了 LoD 树遍历、.RAD 渐进流式加载和 GPU 虚拟页表三项机制,为在浏览器中渲染亿级 splat 场景提供了可复用的工程路径。

正文 · AI 翻译

Spark 是一款专为 Web 打造的动态 3D 高斯泼溅(3DGS)渲染器。它与 Web 上最流行的 3D 框架 THREE.js 集成,并使用 WebGL2 在任意具有浏览器的设备上运行,包括桌面、iOS、Android 和 VR。

Spark 于去年发布,带来了许多其他渲染器所不具备的功能:在同一场景中渲染多个 3DGS 对象的能力、实时编辑与重新打光,以及一个着色器图系统,允许用户创建完全动态的基于泼溅的效果和动画。

在 Spark 2.0 中,我们新增了一个细节层次(LoD)系统,可以在任何设备上流式传输并渲染巨大的 3DGS 世界。当你在世界中移动时,Spark 会自动针对当前视角优化 3DGS 的细节级别,并通过互联网流式传输所需的数据。

在这篇文章中,我们将深入探讨使这一切成为可能的技术细节,并在此过程中学习一些计算机图形学和系统工程知识。已经熟悉 3DGS?跳过介绍,直接跳转到 Spark 2.0 LoD 方法。

3D 高斯泼溅

扫描世界并将其转化为计算机上的 3D 数据,即摄影测量,随着机器学习技术的出现正在快速进步。 3D 高斯泼溅的引入使得在消费级设备上交互式渲染这些扫描数据成为可能。

在传统 3D 图形中,我们使用纹理映射三角形来表示物体表面。但在 3DGS 中,我们转而使用数百万个半透明的彩色椭球体,即泼溅点,它们相互融合以构成所有表面和微小细节。

点击以 3D 查看:使用纹理映射三角网格(左)和高斯泼溅点(右)渲染同一物体。

每个 splat 具有以下属性:其在空间中的中心位置、椭球体 XYZ 轴的半径、三维朝向、RGB 颜色及其不透明度。如果我们忽略朝向,且 splat 位于原点,我们可以用函数 来描述其三维"密度",该函数具有高斯分布轮廓。

点击以进行 3D 交互:调整控制 3D 高斯 Splat 外观的属性:其中心、XYZ 缩放、旋转、不透明度和颜色。

将这些 splat 渲染到屏幕上最常见的方式是画家算法,即按从远到近的顺序对 splat 进行排序,然后将它们逐层叠加绘制,使用"over" 运算符将半透明区域混合在一起。每个 3D 椭球体被投影到图像平面上,近似为一个 2D 椭圆,对于椭圆中的每个像素,我们从其高斯分布计算不透明度,最后将其颜色与之前绘制的 splat 进行混合。

Spark 的起源

Spark 最初是 World Labs 开发的一款内部 3DGS 渲染器,因为现有的网页渲染器存在若干不足,这些不足将在未来限制我们的发展。例如,它们一次只能正确渲染一个 3DGS 对象,无法对泼溅点进行动态动画(俗称"4DGS"),基于不太主流的 3D 框架,或者使用了 并非所有设备都支持的 WebGPU。该渲染器曾亮相于我们 2024 年的大世界模型研究预览以及早期世界展示Lofi Worlds。

点击体验3D:Lofi Worlds——一段由Marble打造的、穿越氛围感3D世界的放松之旅。在Quest 3或Apple Vision Pro上以VR体验效果最佳。

但我们希望任何人都能构建交互式 3DGS 网页体验,因此我们决定将所学经验用于构建一个通用的、开源的 3DGS 渲染器。我们选择基于网页上最流行的 3D 框架 THREE.js 来构建,该框架能够在浏览器中创建复杂的 3D 体验,即使是通过 vibe coding。我们还以 WebGL2 为目标,这是几乎可以保证在当今所有设备上运行的唯一 3D 网页 API。

Spark 与 Marble 同步开发,后者允许用户利用我们的多模态世界模型在网页浏览器中创建 3D 世界。这一具体用例帮助将 Spark 塑造成一个灵活、可由用户编程的 3DGS 处理引擎,同时也展示了使用 Spark 可以构建什么样的应用。

Spark 系统设计

我们希望能够将 3DGS 对象拼接在一起以构建巨大的世界,而要正确做到这一点,必须将所有不同对象中的 splat 按统一的从后到前的顺序进行排序。如果没有这一步,仅进行局部排序的对象看起来像是彼此"粘贴"在一起,而非共存于同一个 3D 空间中。

点击以 3D 体验:仅局部排序(不正确)与全局排序的 splat 对比

3DGS 也是一个快速演进的领域,我们希望用户能够尝试用于重光照、动画、实时编辑或其他创意/交互效果的新技术。我们希望 Spark 足够灵活,能够处理这些用例,而无需不断修改 Spark 的核心系统。

Spark 使用三步算法来解决这些问题:

  1. 从所有 3DGS 对象中生成一个全局 splat 列表,并转换到同一空间中
  2. 针对当前视角,将该全局列表从后到前排序
  3. 按该顺序渲染 splats

1. 生成全局 splat 列表

步骤 1 遍历每个 3DGS 对象,将其 splat 贡献到一个全局列表中。由于每个 3DGS 对象都可以在空间中独立定位和定向,我们至少需要将 splat 变换到同一坐标系中。

点击以 3D 体验:Spark 通过三步流程渲染动态且排序正确的 3D 高斯 Splat:1) 为当前帧生成动画 splat 的全局列表,2) 将 splat 从后到前排序,3) 从后到前渲染 splat。

Spark 借此机会在 GPU 上对每个 splat 运行可定制的数据管道。这开启了各种可能性:重新着色 splat、调整不透明度、基于 SDF 的裁剪、动画过渡、在扫描的 4DGS 帧之间进行插值,等等。该管道可由用户编程,使用 GLSL 或将 节点连接成计算图(类似于 3D 引擎中的着色器图系统)。每个 3DGS 对象都可以运行自己的管道,在场景中混合搭配各种效果。

2. 对 splat 进行排序

虽然第 2 步中的排序在现代 GPU 上是可以实现的,但 WebGL2 提供的编程模型使其代价过高。取而代之的是,Spark 在 GPU 上计算 splat 距离,然后将该列表读回 CPU。随后,这些距离在一个后台 Web Worker 线程中使用两趟基数排序进行排序。Spark 进一步推广了这一方法,允许你同时对 多个视角 执行此操作,每个视角拥有各自的排序顺序。

3. 渲染 splat

一旦我们获得了 splat 的全局列表及其排序,在第 3 步中,我们执行一次实例化绘制调用,一次性绘制所有 splat。每个 splat 被渲染为一个有方向的四边形(严格来说是两个三角形),包围该 splat 投影后的二维椭圆。四个顶点通过自定义的顶点着色器计算,然后片元着色器通过计算高斯分布曲线来确定每个像素的不透明度,最后由 GPU 硬件将颜色混合到帧缓冲区中。

扩展到巨大的世界

自 Spark 首次发布以来,3DGS 在受欢迎程度和规模上都在不断增长。如今的 3D 扫描通常包含数千万个 splat,而 World Labs 正在生成更大、更好的世界,这些世界可以被扩展和组合成巨大的迷宫。

然而,大多数消费级设备只能以交互帧率渲染 100 万至 500 万个 splat。大型场景在显示之前需要下载 100 MB 以上甚至 1 GB 以上的 3DGS 数据。移动设备浏览器对 GPU 内存使用量设有上限,限制了可以可靠地在线分享的世界规模。

Spark 2.0

全新的 Spark 2.0 是一套完整的解决方案,用于在网络上、在所有设备上准备、流式传输并渲染大型 3DGS 场景。

它采用三种图形与系统技术来应对扩展性挑战:

  • 细节层次:准备 splat 的低分辨率版本,并计算针对相机视角应渲染哪些 splat 子集。当 splat 距离过远、无法辨认细节时,通过渲染更少的 splat 来提升渲染性能。
  • 渐进式流式传输:在下载数据时,以从粗到细的方式逐步加载 3DGS 细节,根据相机朝向优先加载最能解析细节的数据。
  • 虚拟内存:为 splat 页表分配一个固定的 GPU 内存池,根据我们在场景中的位置自动换入和换出 3DGS 数据块,从而可以访问通过互联网获取的多个 3DGS 对象中庞大的 splat 池。

细节层次

在计算机图形学中,处理大型 3D 场景的一种常见技术是使用细节层次(LoD)系统,根据与观察者的距离自动调整渲染的细节量。细节也可以降低以获得更高的帧率,或在观察者停止移动时增加。

LoD 的一个经典示例是 Mip-mapping,其中纹理被降采样为一系列较小的纹理金字塔,每一级纹理的尺寸为上一级的一半,顶部仅有一个像素。这使得我们能够在距离相机的任何距离上快速采样一个与屏幕像素大致相同大小的纹理像素。

一个广为人知的现代三角形网格 LoD 系统是 Unreal Engine 的 Nanite,它创建了一个具有不同细节层次的三角形簇层级结构,并根据视点选择部分簇以恰好合适的细节级别进行渲染。

Left: Texture LoD using Mip-mapping. Right: Mesh LoD with Nanite

左:使用 Mip-mapping 的纹理 LoD,采用由低分辨率纹理组成的金字塔结构。
右:使用 Nanite 的网格 LoD,具有三角形簇的层级结构,可选择具有适当细节的网格。

不同的 LoD 方法可以存在于从离散到连续 LoD 方法的连续谱上。离散 LoD 涉及创建从少量到大量 splat 数量的多个不同版本的 splat,然后根据它们的近似边界与相机之间的距离在这些版本之间进行切换。

虽然 Spark 的原始系统设计开箱即用地支持此模型,但这种方法在移动或突然切换版本时会产生"弹出"伪影,并且在将 splat 分组为瓦片时存在可见的边界。

细节层次高斯 splat 树

Spark 的 LoD 设计是一种连续 LoD方法,其中所有 splat 存在于一个层级结构中,即一个LoD splat 树。Spark 沿树的边界切割单独选择 splat,以优化视口内的 splat 细节。

每个内部树节点都是其子节点的较低分辨率版本,通过将 splat 合并为一个新 splat 来形成,该新 splat 近似子 splat 的形状和颜色。这一过程一直持续到树的根节点,即一个大型 splat,它具有对象中所有 splat 的聚合形状和颜色。

3DGS LoD tree

左:通过将输入叶 splat 合并为更大的内部节点 splat,直至单个根 splat,生成的 LoD splat 树。
右:Spark 根据当前视点计算树切割,以选择要渲染的 splat。

利用这棵 LoD splat 树,Spark 通过计算穿过它的"切片"来为当前视口选择最佳的一组 splat 进行渲染。通过设置最大 splat 预算(根据设备类型不同为 50 万至 250 万个 splat),我们确保每帧只需渲染固定数量的 splat,从而实现稳定且高帧率的表现。通过向上或向下调整,我们可以在帧率和 splat 细节之间进行权衡。

点击以3D方式体验:Spark 根据相机视锥体持续调整 3DGS 的细节级别,并按需通过互联网流式传输数据块(以绿色闪烁显示)。

LOD splat 树遍历

Spark 通过遍历 splat 树,在 时间内计算为视点渲染的最佳 LoD splat 子集,其中 是渲染的 splat 预算,与 splat 树的总大小无关。无论场景中全局有多少 splat,Spark 都以大致均匀的时间更新细粒度 splat LoD。该树遍历算法使用一个优先队列:

  1. 从 LoD splat 根节点 开始,计算其屏幕尺寸 ,并将 插入优先队列。
  2. 从优先队列中弹出尺寸最大的 LoD splat 。如果 小于 1 像素或 是叶节点,则将其加入输出集,并重复步骤 2。
  3. 如果将 LoD splat 替换为其子节点会超出 splat 预算 ,则将队列中所有剩余的 splat 移入输出集并停止算法。
  4. 否则,对于 parent 的每个 child,计算屏幕尺寸并将其插入队列。最后,重复步骤 2。

点击以进行 3D 交互:Spark 从粗到细遍历 LoD splat 树,计算一个树切割,使 splat 像素尺寸在 N 个 splat 的预算内保持平衡。

Spark 使用 Rust 实现该算法,并将其编译为 WebAssembly (Wasm),以便在后台 Web Worker 中高效运行,使 LoD 更新异步执行,不影响主渲染循环。

合成 LoD splat 场景

Spark 进一步推广了该算法,通过同时遍历多个 LoD splat 树实例来实现。不再从单个根节点开始,而是为每个 3DGS 对象将其屏幕尺寸和 splat 节点插入初始优先队列。算法的其余部分按此前方式继续执行,同时为场景中所有 3DGS 对象选择需要细化到何种细节级别。

这使得我们只需在空间中任意位置添加 3DGS LoD 对象,即可轻松创建巨大的复合世界,而 Spark 将计算所有 LoD splat 的最佳全局子集来渲染每一帧。

点击以 3D 体验:由多个 3DGS 对象创建的复合世界,每个对象都带有 LoD splat 树。Spark 同时遍历它们,以生成统一的细节级别渲染。

注视点 Splat

Spark 实现了固定注视点渲染,将 LoD Splat 预算偏向视野方向中心。这提高了观察方向的细节级别,将更少、更大的 LoD Splat 分配给视野两侧和观察者后方。

由于 Spark 在 LoD 树遍历过程中计算 LoD Splat 的屏幕尺寸 ,以优先细化最粗糙的 Splat,我们可以调整 来精确控制整个世界的细节级别。如果将 Splat 尺寸加倍为 ,它将被插入到优先级队列的更高位置,并解析为 2 倍更精细的细节。相反,如果将 Splat 尺寸减半为 ,它将位于优先级队列的更低位置,并解析为 2 倍更粗糙的 Splat。

我们将此缩放因子称为注视点缩放系数(foveation scale),它随 splat 视角方向变化,将计算从 调整为 ,最终得到相对 splat 大小为 。

Spark 使用四个 LoD 参数来控制基于视角的细节层次:

  • coneFov0:围绕视角方向的锥体角度,具有 和完整分辨率。
  • coneFov:更大锥体的角度,其细节将由 coneFoveate 降低。
  • coneFoveate:coneFov 边缘处的注视点缩放系数,当角度从 coneFov 变化到 coneFov0 时进行平滑插值。将其设置为 会使 splat 增大 10 倍。
  • behindFoveate:相机后方的注视点渲染缩放比例,从 coneFov 到 180 度之间平滑变化。

点击以进行 3D 交互:Spark 的 LoD 系统使用注视点渲染,将 splat 细节集中在相机注视的方向。

生成 LoD 树

使用其命令行工具 build-lod,Spark 可以将任何 3DGS 文件转换为编码在一种新的可流式传输 .RAD 文件中的 LoD splat 树。或者,它可以在 Web 浏览器中加载任何文件,并使用后台 Web Worker 按需创建 LoD 树。两者运行相同的 Rust 代码,该代码可编译为 Wasm 和原生环境。

Spark 2.0 包含两种用于创建 LoD splat 树的算法:1) 一种快速且紧凑的算法,名为 Tiny-LoD,在 Web 上运行时默认使用;2) 一种质量更高的 Bhatt-LoD,在命令行中默认使用。

这两种方法都是"免训练的",不需要任何参考图像或其他输入,而是直接对 3DGS 数据进行操作。也可以使用其他树生成方法,例如 NanoGS 可用于生成 LoD 树。

Tiny-LoD 算法

此方法旨在"按需"使用,其优先级在于快速生成合理的 LoD splat 树,同时不使用过多内存。它基于我们称为 Quick-LoD 的较早体素八叉树算法,但采用了来自计算基因组学的内存优化技术。

我们将空间划分为立方体网格,并允许该网格的步长按 变化,其中 是对应于 LoD 树层级的带符号整数, 是相邻网格尺寸之间的比率。当 时,这对应于常规八叉树,一种在图形学中常用的 3D 数据结构。每个输入 splat 被插入到网格中 处,其尺寸刚好小于立方体网格尺寸 。我们将每个 splat 放置在包含其中心的立方体中。

我们逐个 进行处理,从包含最小 splat 的最低 开始。对于当前 中包含多个 splat 的每个立方体网格,将这些 splat 合并为一个新 splat。创建一个对应的 LoD 树节点,以之前的 splat 作为子节点。处理完所有立方体后,递增 并重复该过程。此过程持续进行,直到所有输入 splat 都被合并为单个根 splat。

点击以 3D 体验:Tiny-LoD 通过合并落在网格立方体内的 splat 来生成 LoD splat 树,沿层级向上迭代使用更大的网格,直到所有 splat 被合并为单个根节点。

在计算基因组学中,通常需要查找包含相同字母子串的数据。使用哈希表可以轻松完成这一任务,但当键空间很大且值为可变大小的数组时,由于数据结构开销,内存和缓存效率会很低。Tiny-LoD 采用了一种来自计算基因组学的技巧来高效地完成这一任务:

  1. 不使用哈希表,而是为每个插入的 splat 创建一个连续的 数组,其中 。
  2. 按 对此数组进行排序,排序后所有具有相同 的 splat 将在数组中相邻。虽然排序的复杂度为 ,但由于其具有更好的缓存局部性,这通常比哈希更快。
  3. 通过将数组从头到尾分块为具有相同 的 splat 组来遍历网格单元。
  4. 将这些 splat 组合并为新的 LoD splat。
  5. 在下一个更大的 处重复步骤 1。

虽然 看起来像是自然的选择——其中 splat 沿规则的 2 的幂次八叉树向上递归合并——但实践中我们发现 能产生更令人愉悦的效果。使用非整数 时,不规则的网格边界会在我们向上移动层级时打散图案,并减少 splat 细节的大幅变化。更小的基数如 能产生更平滑的细节过渡,但也会导致树更高,遍历和更新速度更慢。默认情况下,Tiny-LoD 使用 来平衡这些因素。

Bhatt-LoD 算法

该方法以 Bhattacharyya 及 Bhattacharyya 距离命名,后者用于计算两个 3DGS 形状之间的统计重叠度。与 Tiny-LoD 类似,它从底层到顶层合并 splats,但根据形状和颜色的相似程度来选择要合并的 splat 对。它旨在用于"离线"场景,在此场景中我们优先考虑质量而非速度。

Bhatt-LoD 遍历所有输入 splat,这些 splat 被组织成一个优先队列,从最小的 splat 开始,逐步处理到最大的 splat。对于每个 splat,它在该 splat 周围的邻域中搜索其他尺寸相近的 splat,并计算一个度量值。它选取相似度度量最优的 splat(如果存在),并将两个 splat 合并为一个新 splat,然后将其插入队列。该过程持续进行,直到优先队列中仅剩一个 splat,该 splat 即为根 splat。

为了比较 splat 和 ,我们定义 。形状相似度由 来衡量,即两个三维高斯密度函数之间的 Bhattacharyya 距离。颜色相似度通过 计算,即它们颜色之间的平方差 。

由于 Bhatt-LoD 始终将 splat 成对合并,如果我们从 个输入 splat 开始,最终树中将有恰好 个 LoD splat。为简化树结构,我们会修剪任何未至少比其子节点大 倍的内部 LoD splat。Bhatt-LoD 的默认值为 ,这使得 LoD splat 树比原始输入 splat 大约大 30-40%。

渐进式流传输

Spark 2.0 定义了一种新的文件格式 .RAD(代表 RADiance fields,即辐射度场),用于压缩 3DGS 数据,并支持随机访问流式传输,以便在数据通过互联网传输时进行渐进式细化。3DGS 对象几乎可以即时显示为所有 splat 的粗略 64K splat 近似。数据块会被获取以优先细化最粗糙的可见 LoD splat,并随着观看者在场景中移动而重新调整优先级。

现有 3DGS 文件格式存在的问题

3DGS 数据最常见的两种文件格式是原始的 .PLY 和 .SPZ,它们代表了两种不同的数据编码风格:面向行和面向列:

  • .PLY:在纯文本文件头之后,依次存储 splat 0 的所有属性,然后是 splat 1 的所有属性,依此类推,这种存储方式称为行序。每个值以 float32 编码,不进行任何压缩。10M splats 包含 SH0..3 时可能占用多达 2.3 GB 的数据。
  • .SPZ:以列序编码数据,先存储所有 splat 的中心坐标,然后存储所有 splat 的不透明度,依此类推。每个属性以更少的位数和降低的精度存储,例如 0..1 的不透明度被编码为 0..255,占一个字节。所有列拼接后作为 GZ 流进行压缩。10M splats 包含 SH0..3 时仅占用 200-250 MB 的数据。

由于 .PLY 文件按行序存储,我们可以在数据接收后立即显示 splat,从而实现渐进式加载。但它没有压缩,且编码精度存在浪费。.SPZ 文件将相似类型的数据按列序存储在一起,从而获得更好的压缩效果。遗憾的是,它无法渐进式加载,因为必须接收完整个文件后,任何 splat 才能拥有其全部属性。

.RAD 文件

为了实现 3DGS 的压缩、高效、可流式传输格式这一目标,我们开发了一种新的文件格式 .RAD。我们的目标是:编解码简单、可扩展、编码精度可选,并支持随机访问。

RAD 文件结构,由可扩展的 JSON 元数据头部和随后可随机寻址的块组成。每个块是一个 RADC 文件,具有 JSON 头部和一个 64K splat 块的属性,按列顺序编码和压缩。

文件结构很简单:头部 RAD0、头部元数据的字节大小、元数据 JSON,随后是一个或多个 64K splat 块。头部元数据包含所有块的偏移量和字节大小,这使我们能够按任意顺序获取块数据。

每个 chunk 本身使用类似的格式:一个头部 RADC、chunk 头部元数据的大小、元数据 JSON,随后是 64K splats 的压缩数据。Splat 属性按列顺序存储,每个属性具有可自定义的编码。每个属性使用 Gzip 进行压缩,由于相似的数据类型被存储在一起,因此压缩效果良好。

由于头部以 JSON 编码,通过使用 version 字段以及添加新的可选字段,确保了未来的可扩展性。数据类型编码和压缩算法通过元数据中的字符串名称来选择,允许未来添加新的字符串。

空间分区 LoD 树

LoD splat 树可以被视为存在于四个维度中:三个空间维度和一个细节层次维度。为了通过流式传输实现渐进式细化,我们需要将 LoD splat 仔细组织成块,存放在 .RAD 文件中。

这里有许多可行的策略,但 Spark 的方法旨在通过将空间递归地细分为更小的区域,使 splat 数据在空间上共置。64K 大小的块从大到小依次填充这些空间区域内的 splat,在块内尽可能多地解析细节。

第一个块没有空间边界,从索引为 0 的根 splat 开始,然后依次添加其子节点,再按尺寸从大到小的顺序添加它们的子节点,直到达到 64K 个 splat。然后我们将空间划分为 AABB 区域,并对每个区域进行递归,在区域内添加 splat,直到填满一个 64K 的块。这些区域会被进一步细分,该过程持续进行,直到所有 splat 都被输出到某个块中。

点击以进行 3D 交互:Spark LoD 树被划分为空间上相邻的块,在 64K 个 splat 内尽可能多地解析细节。

采用此策略,加载的第一个 64K 块 splats 是树中最大的 64K 个 splats,使得 splats 的粗略版本几乎可以立即渲染。每额外加载一个 64K 块的 splats,都会在空间细分区域内提供尽可能多的细节。这样,我们就可以获取对应于观察者附近区域的块,并快速解析细节。

遍历包含缺失块的 LoD 树

Spark 通过加载整个块来流式传输 .RAD 文件,但在第 0 块之后,各块的加载顺序可以是任意的,具体取决于哪些块最能解析视口中的细节。通过跟踪每个块是否已加载,LoD 遍历算法可以快速判断某个 splat 的子节点是否已加载。如果尚未加载,则改为渲染父 splat,待数据接收后再进行进一步细化。

在遍历 LoD splat 树时,Spark 会维护一个已访问块的列表及其顺序,包括尚未加载的块。由于遍历算法从屏幕尺寸最大的 splat 到最小的进行细化,列表中靠前的块包含的 splat 比后续访问的块中的更大。

因此,Spark 利用此块访问顺序来优先处理 .RAD 文件的块获取。它根据相机视角不断重新计算最高优先级的块,并使用 3 个并行 Web Workers 在后台获取和解码数据。

虚拟内存

虚拟内存是一种内存管理技术,通过固定大小的真实"物理内存"池来提供对大量理想化"虚拟内存"的访问。使用页表以固定大小的页为单位,在虚拟地址和物理地址之间进行映射。

Spark 2.0 将这一技术应用于 3DGS,在 GPU 上分配一个固定的 16M splat 池,并自动管理 64K splat GPU "页面"与 .RAD 文件中虚拟 64K 块之间的映射。块根据 LoD 遍历顺序加载到空闲页面中。当页表已满且块的优先级低于需要获取的新块时,块会被替换,采用最近最少使用的方式。

点击以 3D 体验:3DGS 数据被组织为 64K splat 的块/页面,根据相机视角按需加载到统一的 GPU 页表中,并以 LRU 方式与其他数据交换。

Spark 的设计允许多个 .RAD 文件同时获取并共享同一个页表。对于每个 .RAD 文件,我们存储其从 chunk 到页表的映射,以及从页表到文件和 chunk 的反向映射。在遍历多个 LoD splat 树时,我们跟踪 chunk 和文件的访问顺序。由此得到跨所有文件和 chunk 的全局优先级排序,使我们能够优化场景中所有 3DGS 对象的 splat 的获取与存储。

摘要

Spark 是一款面向 THREE.js 和 WebGL2 的 3DGS 渲染器,配备用户可编程的 GPU splat 处理引擎。全新的 Spark 2.0 新增了 3DGS 细节层次(Level-of-Detail)系统,可连续调整细节级别,在你注视的位置渲染 splat 细节。新的 3DGS 文件格式 .RAD 支持渐进式精化的流式传输,而虚拟 splat 分页系统则允许在固定 GPU 内存分配下访问无限的 splat 世界。

探索 Spark 2.0 作品

Starspeed — 作者:James Kane

Starspeed 是一款多人太空飞船射击游戏,配有 10 首合成波原声带和引人入胜的故事,由 Webby 获奖艺术家兼开发者 James C. Kane 制作。该游戏使用 World Labs 的 Marble 和 Spark.js 以及 Blender 和 three.js 制作,STARSPEED 通过 .rad 格式直接在浏览器中流式传输由 100,000,000+ 个高斯泼溅构成的公里级科幻环境。

点击即玩:James Kane 的 Starspeed

沉睡的记忆 — 作者 Hugues Bruyère

Dormant Memories 是 Hugues Bruyère 创作的一系列交互式扫描作品,他是 Dpt. 的联合创始人兼首席技术官,Dpt. 是一家专注于交互式和沉浸式体验的创意工作室。该作品捕捉现实世界中的地点,并以 Marble 构建为可探索的环境,将记录在案的空间与想象的空间相连,探索氛围、记忆以及场所的另一种版本。

点击体验:Dormant Memories,作者 Hugues Bruyère

探索大规模捕捉空间 — 作者 Fujiwara Ryo

HoloLab Inc. 空间信息技术部门的 Fujiwara Ryo 展示了大规模 3D Gaussian Splatting,包含多个捕获场景,最多可达 4000 万个 splats。该体验在智能手机上运行流畅,同时兼容 Quest 和 Vision Pro。

点击体验:探索 Fujiwara Ryū 的大规模捕获空间

3DGS + 你?

如果你觉得这篇文章有趣,来看看我们的 GitHub 仓库。克隆该仓库并试用 Spark 示例。在 Spark 文档 中了解更多关于 Spark 及其功能的信息。了解如何开始使用新的 LoD 系统。

你的项目需要一些 3DGS 数据?试试 World Labs 的 Marble,只需一行文字或一张图片,就能创建一个 3DGS 世界。使用 Marble Studio 将你的创作拼接成广阔无垠的巨大世界。用 Spark LoD 渲染你的世界,制作一个 3D 网页应用,然后分享给所有朋友!

如果你是编程或图形学的新手,现代 LLM 现在已经能够根据几行英文文本生成完整的 THREE.js 游戏。借助 Spark 和 Marble,任何人都可以为网页创建 3D 体验!

Spark 旨在拓展 3DGS 的可能性。如果你认为 Spark 及其 LoD 系统的技术细节对你有帮助,它是开源的,你可以基于其代码和想法进行开发。本文中的每个 3D 示例都是一个单页 HTML 文件,并链接了 3D 资源。在浏览器中查看源代码,然后按你的喜好进行编辑!

最后,如果你觉得这篇内容有趣,并对 World Labs 的愿景感到兴奋,欢迎来加入我们!

来源:World Labs · 空间智能与世界模型 · worldlabs.ai