今日开源[第54期]Spark(@sparkjsdev/spark)源码解读

Spark(@sparkjsdev/spark)源码解读

项目主页:https://github.com/sparkjsdev/spark | 文档:https://sparkjs.dev/
版本:v2.1.0 | 许可:MIT | 语言:TypeScript + Rust/WASM | 依赖:three >=0.180.0


一、项目名称、作者及其介绍、作用与背景

1. 名称与作者

  • 项目名:Spark(npm 包名 @sparkjsdev/spark,README 标题 "An advanced 3D Gaussian Splatting renderer for THREE.js",中文可译作"三维高斯泼溅的先进渲染器")。
  • 作者/组织:由 World Labshttps://www.worldlabs.ai ,李飞飞创立的空间智能公司)官方构建并维护。GitHub 组织 sparkjsdev
  • 版本与许可:v2.1.0,MIT 许可,TypeScript 实现,核心解码与 LOD 用 Rust 编译为 WASM(spark-rs)。

2. 作用

Spark 是一个深度集成进 three.js 渲染管线的高斯泼溅(Gaussian Splatting / 3DGS)渲染引擎。它的核心目标是:把"用多张照片重建出的三维点云(高斯泼溅)"当作与 mesh 同级的普通 three.js 物体来渲染、变换、编辑、动画,并能在 98%+ 的 WebGL2 设备上(包括低端手机)流畅运行。

3. 背景

高斯泼溅是 2023 年以来席卷三维重建界的表示法——用数百万个带协方差的"高斯_blob"来表示场景,比传统 mesh/NeRF 更轻、更真实。但它不在 WebGL 原生渲染栈内:

  • 标准 three.js 没有"泼溅"这种基元;
  • 排序(半透明正确叠加)、海量实例化、动态编辑、LOD 流式加载都是开放难题。

Spark 解决的就是"让 3DGS 在浏览器里成为一等公民"这件事。它和 PlayCanvas 的 spark/SuperSplat、gsplat.js 等是同一赛道,但 Spark 的差异化在于:完整的 dyno 着色器图(shader graph)系统——用户可以用 JS 像搭积木一样组合 GPU 着色逻辑,在 GPU 上实时生成/变形/着色泼溅。

4. 主要功能(README 摘录)

  • 与 three.js 管线融合,泼溅与网格物体可同场渲染;
  • 跨设备可移植,瞄准 98%+ WebGL2 支持,低端移动端也能快渲染;
  • 多泼溅对象同场、正确排序;
  • 支持主流格式:.PLY(含压缩)、.SPZ.SPLAT.KSPLAT.SOG.RAD
  • 多视点同时渲染;
  • 完全动态:每个 splat 可变换、可编辑用于动画;
  • 实时泼溅颜色编辑、位移、骨骼动画;
  • dyno 着色器图系统:在 GPU 上动态创建/编辑泼溅。

二、安装与使用教程、依赖的软件/硬件条件

1. 软件依赖

  • 运行(消费端):任意支持 WebGL2 的现代浏览器(Chrome/Edge/Firefox/Safari 15.4+);若为 HTTPS/localhost 之外场景需安全上下文;three.js >=0.180.0(peerDependency)。
  • 开发/构建:Node.js(用于 npm 脚本、vite、ts-node);Rust 工具链rustc/cargo,用于 npm run build:wasmspark-rs 编译成 WASM);支持 WASM 的浏览器用于跑解码/LOD。
  • 文档站构建(可选):Python + mkdocs-materialpip install mkdocs-materialbrew install mkdocs-material)。
  • CI:GitHub Actions(.github/workflows/build-dist.ymlci-linux.ymlci-windows.yamldeploy-site.yml)。

2. 三种使用方式

(a) CDN + importmap(最轻,零构建) —— 官方 Quick Start 示例,直接写一个 index.html

<style> body {margin: 0;} </style>
<script type="importmap">
  {
    "imports": {
      "three": "https://cdn.jsdelivr.net/npm/three@0.180.0/build/three.module.js",
      "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.180.0/examples/jsm/",
      "@sparkjsdev/spark": "https://sparkjs.dev/releases/spark/2.1.0/spark.module.js"
    }
  }
</script>
<script type="module">
  import * as THREE from "three";
  import { SparkRenderer, SplatMesh } from "@sparkjsdev/spark";

  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(60, innerWidth/innerHeight, 0.01, 1000);
  const renderer = new THREE.WebGLRenderer();
  renderer.setSize(innerWidth, innerHeight);
  document.body.appendChild(renderer.domElement);

  const spark = new SparkRenderer({ renderer });   // 把 Spark 挂进 three 管线
  scene.add(spark);

  const butterfly = new SplatMesh({ url: "https://sparkjs.dev/assets/splats/butterfly.spz" });
  butterfly.position.set(0, 0, -3);
  scene.add(butterfly);

  renderer.setAnimationLoop((time) => {
    renderer.render(scene, camera);
    butterfly.rotation.y += 0.01;
  });
</script>

(b) NPM 安装(推荐,用于打包项目)

npm install @sparkjsdev/spark

随后 import { SparkRenderer, SplatMesh } from "@sparkjsdev/spark";,three 作为 peer 依赖自行安装。

(c) 源码开发/贡献

npm install
npm run build:wasm     # 先编译 Rust -> WASM(spark-rs)
npm run build           # 再构建 Spark 本体(vite 双产物)
# 可选:把远程示例资产下载到本地缓存,离线更快
npm run assets:download
npm start               # 启动开发服务器,默认 http://localhost:8080/

排错时:npm run clean(清 dist/node_modules/rust/target + 资产)后重来。

3. 关键 npm 脚本(package.json)

脚本 作用
build:wasm node rust/build_wasm.js,把 spark-rs 编译为 spark-rs/pkg 的 WASM + JS glue
build build:production + build:dev(vite 双模式,产出 dist/spark.module.jsspark.cjs.js.min 版)
dev 构建 dev 版 + vite 热更(onchange 'src/**/*' 监听重编)
start 同 dev,跑示例服务器
test node --loader ts-node/esm --test test/**/*.test.ts
lint / format Biome 检查/格式化(@biomejs/biome
build-lod cargo run --manifest-path rust/build-lod/Cargo.toml 运行独立的 Rust LOD 离线构建工具
assets:download / assets:compress 下载示例资产 / 把 PLY 压缩成 SPZ
docs / site:build / site:deploy MkDocs 文档站本地预览 / 静态构建 / 部署到 GitHub Pages(sparkjsdev.github.io

4. 硬件/运行条件小结

  • 桌面 GPU 任意;移动端要求支持 WebGL2(几乎全覆盖),低端机靠内置三档画质(low/medium/high,见 src/quality 体系,由 enableLodlodRenderScale 等控制)与动态 LOD 降级保证流畅。
  • 不需要专用 AI 加速;解码/LOD/排序在 Web Worker + WASM 中完成,主线程只做渲染。

三、工作流程与具体的执行步骤

1. 编译期:从源码到双产物

  1. npm run build:wasmrust/build_wasm.js 调用 wasm-pack 风格流程,把 rust/spark-lib 编译为 spark-rs/pkg/*.wasm 与 JS 绑定;
  2. npm run build → vite 以 src/index.ts 为入口,配合 vite-plugin-glsl(内联 .glsl)、vite-plugin-dts(生成 dist/types/*.d.ts)、vite-plugin-arraybuffer(内联 WASM 二进制)打包出:
    • ESM:dist/spark.module.js / .min.js
    • CJS:dist/spark.cjs.js / .min.js
    • 类型:dist/types/index.d.ts
    • 同时附带 dist/assets/worker-*.js(离屏 worker 包)。

2. 运行期:一次渲染帧的完整数据流

Spark 把自己实现为一个 THREE.Mesh 子类(SparkRenderer extends THREE.Mesh),从而无缝插入 three 的 render() 调用。每帧流程:

  1. renderer.render(scene, camera) 触发 SparkRenderer.onBeforeRender(SparkRenderer.ts)。
    • autoUpdate,调用 updateInternal → 进入异步 driveSort + driveLod
    • 计算 renderSize、相机近/远平面。
    • SplatAccumulator 的变换矩阵(renderToView…)写进 uniforms。
    • 写入所有渲染 uniforms:最大标准差 maxStdDev、模糊、LOD 参数、排序纹理 ordering、泼溅数据纹理等。
    • geometry.instanceCount = spark.activeSplats
  2. LOD 驱动(driveLod,worker 内)
    • 计算 pixelScaleLimit;比对相机位姿是否变化 → lodDirty
    • 收集带 LOD 的 SplatMeshinitLodTree 分配 lodId
    • 消费 Pager 分页更新;updateLodTreestraverseLodTrees 得可见索引 → updateLodIndices 写实例索引纹理(lodInstancestextureUI32 索引 DataTexture)。
    • 每帧 traverseLodTrees 生成 raycastIndices 供射线拾取。
    • 超时 3s 未用的 LOD 树释放。
  3. 排序驱动(driveSort,worker 内)
    • readbackDepth():用 readRenderTargetPixelsAsync 按层读回深度到 Uint32Array
    • sortWorker.call("sortSplats32", {numSplats, readback, ordering})(由 Rust/WASM 实现的计数排序)。
    • 得到 activeSplats 与排序索引,上传/创建 orderingTexture(RGBA32UI DataTexture,4096×N)。
    • 标记 dirty,递归处理积压。
  4. GPU 实例化绘制:材质(RawShaderMaterial,GLSL3)以 ordering 次序纹理 + 泼溅数据纹理(Packed/Ext)在着色器中 texelFetch 出每个 splat 的 center/scale/quaternion/rgba,计算协方差椭圆并光栅化。
  5. 离屏/环境模式复用同一管线renderTarget() 渲到离屏 WebGLRenderTarget(可双缓冲);renderCubeMap/renderEnvMap 借助 CubeCamera + PMREMGenerator 生成环境贴图。

3. dyno 着色器图的组装流程(核心创新,详见第四节)

  • 每个 SplatMesh/SplatGenerator 持有一个 GsplatGenerator(一个 Dyno 程序:输入 index:int → 输出 gsplat:Gsplat)。
  • 通过 objectModifiers/worldModifiers/SplatEdit 注入的 dyno 节点(变换、重着色、SDF 编辑、骨骼等)被 constructGenerator 组合成一条管线。
  • DynoProgram 在构造时把整张节点图编译成 GLSL 源码graph.compile() → 模板拼接 {{GLOBALS}}/{{STATEMENTS}}),缓存为 RawShaderMaterial
  • numSplats 会让前后帧失去对应(需重排序);改 generator 会触发 GPU 着色器重编译(首次有可感知卡顿,之后按 identity 缓存)。

4. 加载一个 .SPZ/.PLY 文件的步骤(SplatLoader)

  1. SplatLoader.load(url)loadInternal;或用 new SplatMesh({ url }) 自动走加载。
  2. getSplatFileType 按魔数/扩展名判定格式(PLY=ply、SPZ=解压后 NGSP、SOG=PKZip 内 meta.json、RAD=RAD0.splat/.ksplat 只能靠扩展名)。
  3. 把字节丢进 workerPool.withWorker,在 SplatWorker 内调用 loadPackedSplats/loadExtSplats,其中 WASM 解码(Rust spark-rsspz/ply/ksplat/sogs/rad 解码器)返回 {numSplats, packedArray/extArrays, extra, splatEncoding, lodSplats?}
  4. 封装成 PackedSplatsExtSplats,触发 onLoad
  5. lodSplats 存在,建 LOD 子 PackedSplatsdriveLod 使用。

四、逐个介绍项目的各个文件的内容和作用(按模块)

4.1 根目录配置

文件 作用
package.json 包元数据、依赖(fflate、three peer、spark-rs 本地包)、全部 npm 脚本、ESM/CJS/类型导出矩阵
biome.json Biome lint/format 配置
lefthook.yml Git 钩子(提交前 lint/format)
mkdocs.yml 文档站配置
CHANGELOG.md / LICENSE 版本变更 / MIT 许可
index.html / examples.html 仓库首页 / 示例入口
examples/docs/ 示例(40+ 个 HTML demo)与 MkDocs 文档源
.github/workflows/ CI(Linux/Windows 构建、dist 构建、站点部署)

4.2 src/ —— TypeScript 运行时(核心)

入口与渲染:

  • src/index.ts:公共 API 聚合导出(SparkRendererSplatMeshPackedSplatsExtSplatsdynoSplatLoader、XR、controls 等)。
  • src/SparkRenderer.ts引擎心脏SparkRenderer extends THREE.Mesh,挂载渲染管线;负责 onBeforeRender 钩子、排序/LOD 驱动、离屏渲、环境贴图、多视点。含大量 SparkRendererOptions(外观/裁剪/排序/动态 LOD/注视点/着色器覆盖等)。
  • src/SparkXr.ts:WebXR 总控(SparkXr)、手部追踪(XrHandJointEnum、25 关节常量)、JointSplats extends SplatMesh(把 25 个关节渲染成椭球 splat 手),支持 VR/AR。
  • src/controls.tsSparkControls + FpsMovement(WASD/手柄/XR 移动旋转)+ PointerControls(鼠标拖拽/触摸捏合/双击移动/惯性)。

数据与网格:

  • src/PackedSplats.ts内存与 GPU 数据封装。每个 splat 精确 16 字节(4×uint32):center(float16×3) + scale(uint8 对数, 范围 e-12~e9) + rgba(uint8×4) + 旋转(轴角八面体征 uint8×3)。提供 pushSplat/getSplat/forEachSplat/ensureSplats、GPU DataArrayTextureRGBA32UI,4096³ 上限)、DynoPackedSplats(可在着色器动态读)、与 Worker/GPU 的共享格式。
  • src/ExtSplats.ts:扩展格式(float32 中心 + 各向异性协方差),用于需要更高精度或 CovSplat 的场景。
  • src/SplatMesh.ts场景中的泼溅物体extends SplatGenerator)。持有 packedSplats/extSplats/paged,构造时按优先级建立数据源;每帧 update(FrameUpdateContext) 写 time/recolor/transform/edits;支持 objectModifiers/worldModifiers/skinning、LOD/分页、射线拾取 raycast、资源释放 dispose
  • src/SplatGenerator.tsSplatGenerator extends THREE.Object3D(所有泼溅生成器的基类)。定义 GsplatGenerator/CovSplatGenerator(index→gsplat 的 dyno 程序)、SplatModifier(带缓存地给生成器套修改器)、SplatTransformer/CovSplatTransformer(把 Object3D 的矩阵变成 dyno uniform 变换)、FrameUpdateContextupdateVersion() 机制。
  • src/SplatLoader.tsTHREE.Loader 子类,多格式加载器。魔数/扩展名检测(getSplatFileType)、Web Worker 线程池解码、产出 PackedSplats/ExtSplats。注:SPZ/PLY/SOG/RAD 的解码实际由 Worker 内的 Rust/WASM 完成(非纯 JS)。
  • src/SplatWorker.ts:Worker 封装(SplatWorker)+ 池(NewSplatWorkerPool,默认 4 worker)。含 tryExclusive(独占队列,避免长任务被打断)与 call(name, args) 的消息协议;构造时把 WASM_MODULE post 给 worker 完成 WASM 初始化。
  • src/wasm.tsWASM 胶水。用 Vite 的 ?arraybuffer&base64 内联 spark-rs.wasmWebAssembly.compileinit_wasm({module_or_path}) 实例化,导出 WASM_MODULE Promise 与 isInitialized()
  • src/defines.ts:全局常量。LN_SCALE_MIN=-12/LN_SCALE_MAX=9(尺度编码范围,改此处须同步 splatDefines.glsl)、SPLAT_TEX_*_BITS=11(2048³ 数组纹理上限,2D 数组纹理可达 8G splats)、WASM_SPLAT_SORT=trueSplatFileType 枚举、SplatEncoding/PackedExtra/ExtExtra 等类型。

dyno 着色器图系统(最大创新点):

  • src/dyno.ts:re-export 桶,聚合 src/dyno/*
  • src/dyno/base.ts:图模型核心。Dyno<IOTypes, IOTypes>(节点:inTypes/outTypes + generate() 产出 GLSL 片段)、DynoVal(带类型+变量名的边)、DynoBlock(子图,含 visit() 拓扑排序生成 statements)、dyno()/dynoBlock() 工厂、UnaryOp/BinaryOp/TrinaryOp 辅助、Compilation(收集 globals/statements/uniforms/updaters)。
  • src/dyno/program.ts图→GLSL 编译器DynoProgramgraph.compile() 把节点图编译成 {{GLOBALS}}/{{STATEMENTS}} 模板拼接出的着色器源码,用 WeakMap 缓存 RawShaderMaterial(GLSL3)。DynoProgramTemplate 解析模板三段。
  • src/dyno/splats.ts:splat 专用节点。Gsplat/CovSplat GLSL 结构体定义、readPackedSplat/readExtSplat/readCovSplat(texelFetch + unpack* 解包)、transformGsplat(缩放/旋转/平移/重着色)、splitGsplat/combineGsplat、法线/纹理坐标节点。
  • src/dyno/{math,logic,trig,vecmat,transform,texture,convert,control,uniforms,util,value,types}.ts:标准库节点(加减乘除、比较逻辑、三角函数、向量矩阵、纹理采样、类型转换、uniform 绑定、字面量/值封装、类型定义)。

生成器、编辑、修饰、工具:

  • src/SplatGenerator.ts(见上)/ src/SplatEdit.ts实时编辑SplatEditSdf(SPHERE/BOX/ELLIPSOID/CYLINDER/CAPSULE/CONE/PLANE 等形状)、SplatEdit(一次编辑操作,含 SplatEditRgbaBlendMode 的 MULTIPLY/SET_RGB/ADD_RGBA)、SplatEdits(把 SDF+编辑编码进 GPU 纹理,作为标准管线里逐点修改器,GPU 上实时改颜色+位移)。
  • src/SplatSkinning.ts:骨骼双四元数变形(SplatSkinningMode)。
  • src/SplatAccumulator.ts:跨场景累加所有 SplatGenerator 的 gsplat 到单一缓冲,供统一排序渲染。
  • src/SplatGeometry.ts:实例化几何(每实例一个 splat)。
  • src/SplatPager.ts:分页/流式加载(大场景按需取块)。
  • src/Readback.ts:从 GPU 读回像素/深度(排序深度读回、cube targets 读回)。
  • src/SparkPortals.ts:传送门效果(含 DISK_PORTAL_FRAGMENT_SHADER)。
  • src/generators.ts + src/generators/{static,snow}.tsconstructGrid/constructAxes/constructSpherePoints/imageSplats/textSplats 程序化生成泼溅;generators.static/snow 内置生成器。
  • src/modifiers.ts + src/modifiers/{depthColor,normalColor}.tsSplatModifier 集合与按深度/法线着色修改器。
  • src/splatConstructors.ts:程序化构造泼溅的工具。
  • src/hands.ts:手部关节类型与辅助(与 SparkXr 协同)。
  • src/RgbaArray.ts:RGBA 数组封装(readRgbaArray)。
  • src/shaders.ts + src/shaders/*.glsl:共享 GLSL 片段(splatDefines.glslcomputeUvec4*.glsl 等编码/解码辅助)。
  • src/utils.tsisMobile/isAndroid/isQuest2/isVisionProflipPixelstoHalf/fromHalffloatToUint8setPackedSplat/unpackSplat 等底层工具。
  • src/spz.tstranscodeSpz/writeSpz SPZ 转码与写出。

4.3 rust/ —— Rust/WASM 核心

  • rust/spark-lib/:被编译成 WASM 的算法库(spark-rs)。lib.rs 聚合模块:
    • 格式编解码:ply/spz/ksplat/sogs/rad/antisplat/csplat/gsplat/tsplatGslpat/GsplatArray 数据结构,含 SPZ 量化 roundtrip 测试)。
    • LOD 聚簇:sh_clustering(球谐聚簇)、bhatt_lodquick_lodtiny_lodchunk_tree(分层分块树)。
    • 排序:ordering(sortSplats32 计数排序)、symmat3(对称阵)。
    • 变换/射线:splat_encodedecoder(流式 ChunkReceiver)。
    • 通过 wasm-bindgen 暴露给 JS,供 SplatWorker 调用。
  • rust/spark-rs/:独立的 Rust 消费端 crate(decoderext_splatslod_treepacked_splatsraycastsorttransform),README 说明其用途,pkg 被 package.jsonfile:rust/spark-rs/pkg 本地引用。
  • rust/build-lod/:离线 LOD 构建 CLI(main.rs + gpu_sh_clustering.rs),npm run build-lod 触发。
  • rust/build_wasm.js / build_rust_wasm.sh / build_rust_wasm.ps1 / .cargo/config.toml:WASM 构建脚本(跨平台)。

4.4 scripts/ —— 工程脚本

download-assets.js(拉示例资产)、clean-assets.jscompress-to-spz.js(PLY→SPZ)、copy-site-files.js/clean-site-files.js/clean-site.js/serve-site.js/deploy-site.js/rename-assets-to-static.js/replace-urls.js(文档站构建与部署)。

4.5 dist/ —— 构建产物

ESM/CJS/.min、类型声明(dist/types/*.d.ts,含 dyno/ 子目录完整类型)、worker 包、版本 commit.txt。通过 .gitattributes/git update-index --assume-unchanged dist/* 避免误提交。


五、优势、不足、创新点与亮点

1. 优势

  • 一等公民集成SparkRenderer 直接是 THREE.MeshSplatMeshObject3D——泼溅与 mesh、灯光、相机、three 生态(OrbitControls、后处理、XR)自然融合。
  • 跨设备高性能:瞄准 98%+ WebGL2,低端手机靠三档画质 + 动态 LOD + 注视点降级(foveation)保证流畅;排序/解码/LOD 全在 Worker+WASM,主线程只渲染。
  • 格式覆盖广:PLY(含压缩)/SPZ/SPLAT/KSPLAT/SOG/RAD 全覆盖,自动魔数检测。
  • 真正动态:每个 splat 可在 GPU 上被变换、重着色、SDF 编辑、骨骼动画——这是多数竞品只做到"静态查看到加载"的差距所在。
  • 流式与 LODSplatPager 分页 + Rust chunk_tree/sh_clustering LOD,支持超大场景按需加载与多分辨率。
  • 生产级工程:MIT、完整类型声明、Biome lint、CI(Linux+Windows)、文档站、40+ 示例,易于二次开发。

2. 不足

  • 学习曲线陡:dyno 着色器图是独特的编程模型,新手需同时理解 three.js、GLSL 与 dyno 节点图,门槛高于直接用 mesh。
  • 包体与构建复杂:依赖 Rust 工具链构建 WASM,源码贡献门槛高;dist 体积与 WASM 初始化有成本。
  • three 强绑定:peer three>=0.180.0,锁定较新版本,与旧 three 项目不兼容。
  • WebGL2 下限:不支持 WebGL1,极老设备无法运行(但作者宣称 98%+ 覆盖已足够)。
  • 排序仍依赖深度读回readbackDepth 每帧读回深度做 CPU 侧计数排序,理论上存在带宽与延迟开销(作者注释称 JS 与 WASM 排序耗时差异不大,故 WASM_SPLAT_SORT 默认开但影响有限)。

3. 创新点与亮点

  1. dyno 着色器图(Dyno Shader Graph)——项目最大亮点。用 TS 以"节点+边(带类型)"搭出计算图,DynoProgram 在运行时把图编译成 GLSL(RawShaderMaterial,GLSL3),并用 WeakMap 按程序身份缓存材质、按需重编译。这让"在 GPU 上动态生成/编辑泼溅"从"手写 GLSL"变成"搭积木",是 3DGS 领域少见的可组合 GPU 程序抽象
  2. 16 字节紧凑编码 + 2048³ 数组纹理——center(float16)/scale(uint8 对数)/rgba(uint8)/旋转(八面体征)把每 splat 压到 16B,配合 DataArrayTexture(211×211×2^11,最高 8G splats),兼顾内存、缓存与上限。
  3. Rust/WASM 解码与 LOD 内核——SPZ/PLY/SOG/RAD 解码、sh_clustering/bhatt_lod/chunk_tree LOD 聚簇、计数排序全用 Rust 编译成 WASM,在 Worker 内运行,性能与安全性俱佳,且 spark-rs 还能作为独立 Rust crate 复用。
  4. 统一累加 + 多线程驱动架构——SplatAccumulator 把全场景 gsplat 汇成单一缓冲,排序与 LOD 各自在独占 worker(tryExclusive 队列)中异步驱动,主线程零阻塞。
  5. GPU 实时 SDF 编辑——SplatEdit 把多个 SDF 形状(球/盒/椭球/圆柱/胶囊/锥/平面)编码进纹理,在 dyno 管线里以 softmax 混合逐点实时改颜色+位移,支持风、火、水、变形等动画,无需回 CPU。
  6. 骨架动画与 XR 手部——SplatSkinning 双四元数骨骼变形;SparkXr + JointSplats 把 WebXR 25 关节追踪渲染成椭球 splat 手,拓展到 VR/AR。
  7. 多格式 + 程序化生成——既能加载真实重建,也能用 textSplats/imageSplats/constructGrid 等程序化生成泼溅,并内置 snow/static 生成器与 depth/normal 着色修改器,开箱即用。
  8. 多视点/离屏/环境贴图——同一管线复用为 renderCubeMap/renderEnvMap/renderTarget,支持多相机同时渲染与 splat 参与环境光照。

说明:本解读基于对仓库 README、package.jsonsrc/ 全部核心模块(SparkRenderer/PackedSplats/SplatMesh/SplatLoader/SplatWorker/wasm/defines/SplatGenerator/SplatEdit/SparkXr/controls)、src/dyno/*(图模型与 GLSL 编译器)、rust/spark-lib/src/lib.rs 模块组织,以及示例/文档/CI 结构的实际抓取,关键结论均锚定在真实代码与文件上。

posted @ 2026-08-29 16:07  zhang-yd  阅读(22)  评论(0)    收藏  举报