
拍一圈照片,就能生成一个可交互的 3D 世界,已经不是什么新鲜话题了。但问题是如何把一个大世界塞进普通人的手机浏览器里。
就在刚刚,李飞飞旗下 AI 世界模型公司 World Labs 发布并开源了一个最新成果:Spark 2.0。
这个专为网页端设计的动态 3D 高斯点云(3DGS)渲染引擎,让在任何设备的浏览器里流畅运行上亿粒子的超大 3D 场景,开始逐渐成为现实。
为什么把亿级粒子的 3D 世界塞进手机这么难?
你可能听说过「3D Gaussian Splatting」,简称 3DGS。用一句话解释,它是一种把真实场景变成 3D 可交互内容的技术,不用建模,拍一圈照片就能生成。
和传统 3D 建模用三角形面片不同,3DGS 用的是数百万个半透明的彩色椭球体,每一个叫做一个「splat」(泼溅体/斑点)。
左侧使用纹理映射三角网格,右侧使用高斯斑点,对同一对象进行渲染。
每一个 splat 并不是一个简单的点,而是一个有完整「人格」的椭球体。它记录着自己在空间中的位置、三条轴的半径长短、朝向角度、RGB 颜色值,以及透明度。
最关键的是透明度这个属性。它决定了这个 splat 在叠加时对周围的影响权重。如果把单个 splat 的空间密度画出来,你会得到一条高斯曲线:中心最实,向外逐渐虚化,边缘自然消融进背景里。
正是这种「软边界」的叠加方式,让数百万个 splat 堆在一起之后,能呈现出砖墙的颗粒感、树叶的透光感、玻璃的反射,而不是一堆硬边三角形拼出来的塑料质感。
效果好,信息量也大。一个高质量的 3DGS 扫描场景,动辄几千万个 splat,文件体积轻松突破 1 GB。
这就带来了一个棘手的问题:普通手机能流畅渲染的上限大概是 100 万到 500 万个 splat,比动辄 4000 万的高质量扫描差了整整一个数量级。
现有渲染器也没法把多个扫描对象放在同一个场景里正确渲染,要么只能单独渲染一个,要么排序乱掉、对象「贴在」彼此表面上,看起来一团糟。
于是乎,Spark 应运而生。根据官方博客介绍,Spark 最开始是 World Labs 自己用的内部工具。World Labs 需要在网页上展示 3DGS 生成的世界,但市面上的渲染器都有硬伤,有的只能渲染单个对象,有的依赖 WebGPU(很多设备还不支持),有的不支持动态动画。
几番对比下来,他们决定干脆自己造一个。
他们选择的技术底座是 THREE.js,Web 上最流行的 3D 框架,运行在 WebGL2 之上,几乎覆盖所有现代设备。核心渲染逻辑分三步走,先在 GPU 上生成跨对象的全局 splat 列表,再统一按从远到近排序,最后一次性渲染完毕。
「全局排序」听起来平平无奇,实则是让多个 3DGS 对象共存于同一场景、不互相穿模的关键所在。Spark 还在此基础上开放了一套 GPU 处理流水线,用户可以对每个 splat 做重新上色、透明度调整、动态动画等自定义操作,用 GLSL 编写,或者像 Blender 那样连节点图来实现。
1.0 版本解决了多对象渲染的问题,但 4000 万 splat 的场景依然是一道跨不过去的坎。这才有了 Spark 2.0。
让设备永远只渲染「够用」的信息量
Spark 2.0 的核心是三项技术的组合,LoD 细节层级、渐进式流式加载和虚拟内存管理。单独拿出来看,每一项都有先例可循,但三者合力,才撑起了在手机浏览器里流畅渲染亿级 splat 世界的能力。
1. 连续 LoD 树:把好钢用在刀刃上
LoD(Level of Detail)在游戏圈早已是成熟概念。近处的树用几千个三角形,远处的树只留几十个,按需分配,省算力。Unreal Engine 的 Nanite 系统也是这个思路,把三角形细节和视距挂钩,自动缩放。
Spark 2.0 把同样的逻辑搬到了 splat 上,做得更彻底。
离散切换几个版本容易产生画面「跳变」,Spark 的做法是构建一棵完整的「连续 LoD 树」,每个内部节点都是其子节点 splat 融合后的近似版本,层层向上汇聚,最终到达根节点,也就是整个场景最粗粒度的单一 splat。
渲染时,系统根据当前视角在这棵树上动态划一刀,靠近视角的区域取底层细节,远处取高层粗粒度。
整个过程受一个固定的 splat 预算约束,移动端约 50 万,桌面端约 250 万。场景里总共有多少 splat 都无所谓,实际送上 GPU 的数量始终稳定在预算范围内,帧率自然稳了。
在此之上,Spark 还引入了「注视点渲染」(Foveated Rendering),把更多预算集中分配给你正在看的方向,边缘和背后的区域细节自动收窄。这个效果放在 VR 设备上尤其直观,通常需要眼动追踪才能实现,Spark 用固定锥形区域近似模拟,同样奏效。
2. 全新 .RAD 格式:像刷短视频一样「流式」加载
渲染效率的问题解决了,传输效率的问题同样棘手。现有的 3DGS 文件格式有两个:.PLY 和 .SPZ。前者未压缩,10M splat 高达 2.3 GB,虽然可以边下边显示,但体积实在吃不消。
后者用列式存储加 Gzip 压缩,同等数据量压缩到 200-250 MB,代价是必须等整个文件下载完才能显示,因为每个 splat 的属性分散在文件各处,缺了哪一段都拼不出完整内容。
为了鱼和熊掌兼得,Spark 2.0 设计了新格式 .RAD(RADiance fields)。它把 splat 数据切成每块 64K 个 splat 的独立小块,分别压缩,并在文件头中记录所有块的字节偏移位置,支持随机访问任意一块。
第一块永远是整个场景最粗粒度的 64K 个 splat,下载完毕后场景轮廓立刻可见。此后系统根据视角判断哪些区域最需要细化,优先拉取对应的数据块,画面从模糊逐渐推演出细节。3 个并行的 Web Worker 线程在后台同步拉取和解码,你走到哪,细节就跟到哪。
3. GPU 虚拟内存:在有限显存里装下无限空间
流式加载解决了带宽的问题,但 GPU 内存的硬上限依旧是个难啃的骨头。移动端浏览器对显存有严格约束,塞不下整个 4000 万 splat 的场景。
Spark 2.0 借鉴了操作系统的虚拟内存机制来应对这个问题。
系统会在 GPU 上分配一个固定内存池,上限 1600 万个 splat,用一张页表记录哪些 .RAD 数据块当前驻留在 GPU 上。需要渲染某个区域时调入对应的块,内存满了就按最久未使用的顺序换出旧块。
得益于这一机制,不同来源的 3DGS 场景可以共享同一个内存池。理论上,只要网速跟得上,无数个独立的扫描场景可以无缝拼接成一个无限大的世界。
一行链接,交付世界
Spark 2.0 发布之后,李飞飞也第一时间公开表态,「Spark 2.0 现在可以在任何设备上流畅播放超过 1 亿个 splat 对象,非常荣幸能为基于 Web 的 3DGS 渲染开源生态系统做出贡献。」
她没有着重强调「做到了什么」,而是把重点放在「为开源社区贡献了什么」。这个表述耐人寻味。3DGS 渲染是一个仍在快速演进的领域,单靠一家公司推不动整个生态,开源才是加速这件事的正确姿势。
从已有的落地案例来看,开发者确实在用 Spark 做各种方向的尝试。Webby 奖得主 James C. Kane 独立开发了一款名为 Starspeed 的多人宇宙飞船射击游戏。
整个游戏场景由超过 1 亿个 splat 构建,附带 10 首合成波风格原声音乐,全部通过浏览器以 .RAD 格式流式加载,惊艳的科幻环境可以直接在网页里跑起来。
附体验地址🔗:https://starspeed.game/
艺术方向则有 Hugues Bruyère 的《Dormant Memories》。他是互动体验工作室 Dpt. 的联合创始人,这个系列把真实地点的 3D 扫描和想象中的空间并置在一起,做成可探索的交互环境。现实与虚构之间的边界在 splat 颗粒感里变得模糊,倒是意外地切题。
附体验地址🔗:https://smallfly.com/dormant_memories/
来自 Hololive 空间信息技术部门的藤原龍则用 Spark 渲染了多个大型真实捕获场景,单场景最高达到 4000 万 splat,在智能手机、Quest 和 Vision Pro 上均能流畅运行。
附体验地址🔗:https://works.lilea.net/spark/
这些来自开发者的多元化尝试,充分证明了 Spark 2.0 在不同设备和应用场景下的强悍实力。但这仅仅是故事的一半。
对于一家致力于打造「AI 世界模型」的公司而言,李飞飞团队的野心绝不止于提供一个开源的渲染工具。如果说 Spark 2.0 解决了「如何流畅观看」的最后一步交付难题,那么「如何低门槛地创造」这些 3D 内容,才是他们真正的杀手锏。
Spark 和 World Labs 的创作平台 Marble 深度绑定,用一行文字或一张图片在 Marble 里生成 3D 世界,用 Marble Studio 把多个世界拼合成更大的场景,再用 Spark 渲染成可分享的网页体验,这条链路目前已经跑通。
技术进步往往以「强无止境」为最高原则,但有时「够用」或许才是最合适。Spark 2.0 讲的正是这么一个故事。
而让设备在任何时候只渲染「刚好够用」的 splat,这个想法本身并不新鲜,但把它落地到网页端的渲染上,还要同时兼容手机浏览器和 Quest,每一步都是实打实的工程问题。
当 AI 能生成无限大的 3D 世界时,我们用什么载体把它交付给每一个普通人?现在,World Labs 给出的最新答案是一个网页链接。