量子位公众号QbitAI报道,李飞飞的公司World Labs最近发布了Marble模型的更新版Marble 1.1及Marble 1.1-Plus。
在新版本发布后不久,该公司又宣布开源了3D高斯溅射渲染引擎Spark 2.0。
Spark 2.0是一个基于Three.js构建的渲染平台,能够实现大规模3D场景流畅加载和跨设备展示。用户可以通过WebGL2技术,在桌面、iOS、Android和VR等多种终端上体验由1亿多个泼溅点构成的复杂虚拟世界。
在官方博客中,团队详细介绍了Spark 2.0的技术特点,并展示了多个高精度渲染实例。其中一个Coit Tower场景包含了超过四千万个泼溅点,却能在浏览器中实现流畅交互。

相较于传统的3D建模方法,3D高斯溅射技术使用大量的半透明椭球体来构建图像,使得画面细节更加真实细腻。

每一个这样的椭球体由五个属性定义:位置、XYZ轴的缩放比例、旋转角度、颜色和透明度。渲染时通常遵循画家算法,按照从远到近的顺序叠加这些小椭圆,从而形成最终图像。

李飞飞团队自豪地宣布Spark 2.0现已能够在各种设备上流式传输超过一亿个泼溅点,并且能够支持基于网页的3D高斯溅射渲染生态系统的开发工作。
Spark的前身是在内部使用的3D高斯溅射引擎,由于当时市面上缺少优秀的web渲染解决方案,团队决定将其开源以服务更多的开发者社区。

什么是splat?
早期版本曾参与2024年大型世界模型预览和Lofi Worlds项目展示。随后更名为Spark,并向公众开放了源代码。
Spark建立在流行的THREE.js框架上,并采用了WebGL2技术,确保所有设备上的稳定运行。
研发团队表示,在开发Spark的过程中始终与Marble模型保持同步更新。
为了实现更高效的大规模3D场景渲染,新版本的Spark集成了多项关键技术:

细节层次技术(LoD):根据视角智能筛选需要渲染的部分,并减少远距离区域的细节以提高性能;
渐进式流式加载策略:优先下载当前视图所需的数据块,随着更多数据的加载场景逐步细化;

Spark系统设计
虚拟内存机制:为3D高斯溅射数据分配固定大小的GPU缓存池,并根据用户位置自动更新数据,实现高效访问。
Level-of-Detail技术是处理大型3D场景的一种经典方法。它允许系统在需要时降低细节水平以提高性能,或提升细节等级来呈现更加精细的画面。
在应用Level-of-Detail时,Mipmap纹理映射是一种常见做法:通过生成不同分辨率的纹理层级实现快速采样匹配屏幕像素尺寸的效果。

Level-of-Detail技术可以分为离散型和连续型。前者需要提前准备多个版本的数据模型,根据距离切换使用;而后者则能提供平滑过渡效果。
Spark采用了连续型Level-of-Detail方案,通过构建层级化的高斯溅射树实现无缝细节调整。

该平台内置了两种生成算法:Tiny-LoD适用于实时渲染场景,Bhatt-LoD则更适合离线处理。这两种方法都不需要额外的训练数据即可直接运行。
Spark定义了一种名为RAD的新文件格式,用于支持渐进式加载和优化网络传输环境下的3D高斯溅射渲染。
采用这种格式后,对象可以立即以一个包含64K个泼溅点的基本版本展示,然后系统根据视角动态调整优先级获取更多细节数据。
虚拟内存技术通过分配固定大小的GPU缓存池,并建立页表映射关系来提高内存使用效率。

Spark 2.0在此基础上进一步优化了内存管理机制,为每个RAD文件维护两套映射关系:从数据块到内存页以及反向映射。这样可以确保在跨多个3D场景时,能够高效地加载和存储数据。
官方博客中还详细解释了许多其他的技术细节,有兴趣的读者可以通过链接访问了解更多信息:
- https://www.worldlabs.ai/blog/spark-2.0#lod-splat-tree
- 渐进式流式加载(Progressive Streaming):采用“从粗到精”的加载策略,优先下载能最优化当前视角细节的数据。随着数据逐步下载,场景会不断细化,实现流畅的渐进式呈现。
- 虚拟内存(Virtual Memory):为splats页表分配固定的GPU内存池,根据用户在场景中的位置,自动置换3D高斯溅射数据块。借助这一技术,即使是通过网络获取的海量跨对象splats数据,也能被高效访问。
下面具体来看。
Level-of-Detail
在计算机图形学领域,Level-of-Detail是处理大型3D场景的经典方案就是。它能根据物体与观察者的距离,自动调整渲染细节。当需要提升帧率时,可以降低细节等级;当用户静止观察时,则可以提高细节等级,呈现更精细的画面。
Level-of-Detail的典型应用是Mipmap纹理映射:
将一张纹理图片逐级下采样,生成一组分辨率依次减半的纹理金字塔,最顶层是单个像素。这一技术能确保在任意距离下,都能快速采样到与屏幕像素尺寸匹配的纹理数据。
Level-of-Detail的实现方案可分为离散型与连续型两大类。
离散型方案需要预先生成多套不同splat数量的模型版本,再根据物体包围盒与相机的距离,切换渲染不同版本。这种方法存在明显缺陷:
当用户在场景中移动时,模型细节的突然切换会产生“跳变”伪影;同时,将splats分块处理时,块与块之间的边界也会清晰可见。
Spark采用的是连续型Level-of-Detail,核心是为所有splats构建一个层级化结构——Level-of-Detail Gaussian splat tree。

Spark会沿着该树的边界,精准筛选出最适合当前视口的splats子集,实现平滑无断层的细节过渡。

Spark 2.0内置了两种Level-of-Detail Gaussian splat tree生成算法:
- Tiny-LoD算法:一种快速且轻量的算法,默认用于网页端的实时生成场景。
- Bhatt-LoD算法:一种高精度算法,默认用于命令行工具的离线处理场景。
这两种算法均为无训练依赖的方案,无需参考图像或其他额外输入数据,直接对3D高斯溅射数据进行处理即可。除此之外,Spark也兼容其他第三方生成算法,例如NanoGS。
Progressive Streaming
Spark 2.0定义了一种全新的文件格式——.RAD(全称Radiance Fields,辐射场)。该格式不仅能有效压缩3D高斯溅射数据,还支持随机访问流式加载,实现了场景的渐进式精细化渲染,完美适配网络传输场景。
采用RAD格式后,3D高斯溅射对象能立即以一个包含64Ksplats的粗糙版本呈现,随后系统会根据用户视角,优先获取用于优化可见区域细节的数据块,实现动态的优先级调整。

LoD splat tree本质上是一个四维结构:包含三维空间维度与一维细节层次维度。
要实现流式加载的渐进式精细化渲染,必须将LoD splats ,以合理的方式划分到RAD文件的各个数据块中。
实现这一目标的策略有很多,Spark采用的策略核心是空间邻近性优先:
将三维空间递归划分为更小的区域,每个数据块都会按“从大到小”的顺序,填充对应空间区域内的splats,确保每个数据块都能最大化呈现该区域的细节。

视频链接:https://mp.weixin.qq.com/s/4m-RUPdLnzvXSx-cyBqhsQ
Virtual Memory
虚拟内存是一种经典的内存管理技术,通过划分固定大小的内存页,构建页表映射关系,用有限的物理内存,模拟出容量巨大的虚拟内存空间。
Spark 2.0将这一技术创新性地应用于3D高斯溅射渲染:
它会在GPU中预先分配一个固定大小的内存池(容量为1600万个splats),并构建一套页表映射机制,将GPU中的 64K splats“内存页”,与RAD文件中的64K泼溅点数据块一一对应。

数据块的加载与置换规则如下:
- 根据LoD splat trees的遍历结果,将高优先级的数据块加载到空闲的GPU内存页中。
- 当GPU内存池被占满,且需要加载新的高优先级数据块时,会采用LRU算法,将优先级最低的内存页中的数据块置换出去。
Spark的这一设计具备极高的灵活性:它支持同时加载多个RAD文件,并让这些文件共享同一个GPU内存池。对于每个RAD文件,Spark都会维护两套映射关系:从数据块到内存页的映射,以及从内存页到文件和数据块的反向映射。
在对多个细节层次泼溅树进行遍历时,Spark会统一记录所有文件的数据块访问顺序,最终生成一个全局数据块优先级列表,从而实现跨所有3D高斯溅射对象的加载与存储优化。
官方Blog中还介绍了更多技术细节,感兴趣的童鞋传送门在这里:
https://www.worldlabs.ai/blog/spark-2.0#lod-splat-tree
参考链接:https://x.com/i/trending/2044161909943918948
