Gaussian-Splat-Lite

WilliamLiu-1997Apache-2.0活跃维护

面向 Three.js 的高性能 3D Gaussian Splatting 渲染器,支持 WebGPU 和 WebGL2,可加载 PLY、SPZ 等格式并实现流式 LOD,方便在网页端流畅展示大规模 3DGS 场景。

High performance 3D Gaussian Splatting (3DGS) renderer for Three.js. WebGPU and WebGL2. Supports PLY, SPZ, Streaming LOD including SOG, RAD and LCC2.

v1.7.0发布于 2026-11-06 09:18 UTC315star37fork同步于 2026-11-11 00:00 UTC

怎么上手

由 README 提炼,执行前请确认
npm install gaussian-splat-lite three
硬件要求按 README 说明

README 未说明显存或 GPU 型号要求;渲染依赖浏览器 WebGPU 或 WebGL2 后端,WebGPU 不可用时自动回退到 WebGL2。

下载:源码 zip·GitHub Releases(安装包)本站不镜像安装包

项目说明

由 README 自动翻译提炼

Three.js 的 3DGS 渲染器,支持 WebGPU 和 WebGL2,可流式加载大场景

面向 Three.js 的高性能 3D Gaussian Splatting 渲染器,支持 WebGPU 和 WebGL2,可加载 PLY、SPZ 等格式并实现流式 LOD,方便在网页端流畅展示大规模 3DGS 场景。

核心能力

  • 同一套 Three.js 场景 API 可切换 WebGPU 或 WebGL2 渲染
  • 用 RadStreamScheduler 等调度器按相机移动流式加载 LOD 细节
  • 支持 PLY、SPZ、SOG、RAD 格式,可加载 URL、文件或字节
  • 提供随机透明渲染模式,并可用实验性神经降噪平滑噪点
  • 支持离屏渲染出图像、立方体贴图和用于反射的环境贴图

容易踩的坑

Three.js 版本需 >=0.187.0;WebGPU 下必须先 await renderer.init() 再构造 GaussianSplatRenderer;流式调度器需先启动 update 循环再 await firstRenderable;LCC2 与拆分 SOG/RAD 需把索引文件和配套文件放在一起。

内容由模型根据 README 生成,可能不完整或不准确,以官方文档为准。看原文 README

最近发版

5 个版本v1.7.0
  1. v1.7.0最新正式版2026-11-06 · 2026-11-06 09:18 UTC

    Changelog

    Changed

    • RAD and SOG models with SH codebooks keep one shared codebook instead of per-Splat SH coefficients, including when streaming. CPU and GPU memory used by Splat attributes is reduced by up to 25% / 43.75% / 62.5% for SH1 / SH2 / SH3, respectively; actual savings depend on codebook size and exclude other rendering and loading overhead. Streamed RAD inputs with codebooks fit more detail in the same memory budgets.
    • Improved stored Splat rotation precision with 32-bit smallest-three quaternions. Existing model files remain compatible; reload live viewers when upgrading.

    Added

    • Added utils.encodeQuatSmallestThree32() and utils.decodeQuatSmallestThree32().

    Removed

    • Removed alpha, color, and sh from postDecode inputs and outputs. Load-time transforms now expose only position, scale, quaternion, and opacity, preserving shared SH codebooks. Use opacity for transparency and kernel changes, and mesh properties or SDF edits for display color changes.
    • Removed utils.encodeQuatOctXy1010R12() and utils.decodeQuatOctXy1010R12(); use the smallest-three utilities for the new internal rotation encoding.
  2. v1.6.22026-11-03 · 2026-11-03 04:23 UTC
    查看更新说明

    Changelog

    Changed

    • Radial sorting now uses camera distance instead of squared distance on WebGL and WebGPU. This changes how closely spaced Splats share sort keys, especially with fastSort.
  3. v1.6.12026-11-02 · 2026-11-02 08:48 UTC
    查看更新说明

    Changelog

    Added

    • Added Lcc2StreamScheduler for LCC2 scenes with SOG, SPZ, or PLY chunks, camera-driven LOD, shared budgets across inputs, environment loading, and visibility fades. See LCC2 streaming.
    • The viewer opens LCC2 scenes from an index URL or a local folder containing the index and companion files.
  4. v1.6.02026-11-01 · 2026-11-01 10:25 UTC
    查看更新说明

    Changelog

    Added

    • RAD and SOG streaming inputs accept a transform (THREE.Matrix4) that places each model in the scheduler's group, including several instances of the same URL. setSourceSettings() moves an input without reloading its data.
    • Streamed SOG inputs accept their own lodBaseDistance and lodMultiplier. setSourceSettings() also changes an input's LOD settings and environment at runtime.
    • RAD and Streamed SOG support addSource() and removeSource() with stable source IDs, preserving other inputs' loaded data. sourceIds lists the current IDs, which also identify inputs for setSourceSettings() and getSourceSettings().

    Changed

    • gsl-build-lod uses a uniform SH codebook limit of 262144 entries for SH1, SH2 and SH3.
    • Breaking: Raised the minimum Three.js version to r187 and removed the r186 runtime compatibility patch.
    • Neural denoising uses a depth-only render target when exposing depth on the WebGL2 fallback, reducing GPU texture memory.
    • Breaking: RAD and Streamed SOG schedulers always start empty and no longer accept constructor sources or expose initialized. Add each input with await streaming.addSource(options) to wait for its metadata. firstRenderable waits for data added after construction.
    • RAD streaming retains each input's SH degree and consolidates storage only when new detail needs space, while keeping existing detail visible and continuing to load.
    • RAD streaming reduces main-thread work when adding or removing inputs and allocating new storage.
    • RAD streaming moves SH codebook copies off the main thread.
    • Streamed SOG reduces oversized regions toward each input's own median region size when measuring LOD distance.
    • RAD and Streamed SOG streaming use less CPU memory for loaded detail.
    • Sorted Splats draw faster on the WebGPURenderer WebGL2 fallback, now matching WebGLRenderer on Apple GPUs; native WebGPU also draws them slightly faster. Rendered output is unchanged.
    • Node Splat materials now ignore GaussianSplatRenderer.material.opacity, matching the classic WebGL path. Use SplatMesh.opacity to control model opacity.
    • Drawing Splats on native WebGPU does slightly less work per vertex. Rendered output is unchanged.

    Fixed

    • Removing a RAD input during initial loading no longer leaves stale page requests or resolves firstRenderable before remaining data is visible.
    • Repeatedly replacing RAD inputs of different sizes no longer accumulates retired directories or exhausts shared directory addresses.
    • RAD index textures shrink with their selected detail so retained capacity stays within the page memory budget.
    • Preserved named Worker errors so the viewer can fall back to ordinary loading for RAD files without LOD.
    • The viewer Inspector reports rendered FPS correctly when animation ticks are skipped with Three.js r187 and resets its timing when reopened.
    • Cube capture keeps its mip chain allocated while rendering the six faces and generates mipmaps only after the last face.
    • Neural denoising restores render-target viewport and scissor settings independently of the canvas pixel ratio.
  5. v1.5.42026-10-29 · 2026-10-29 10:32 UTC
    查看更新说明

    Changelog

    Changed

    • gsl-build-lod updates SH codebook clustering to balance conversion speed and view-dependent color accuracy.

用户点评

登录用户的真实使用记录,可按版本和硬件筛选
共 0 条

    还没有人点评。第一个说出真实体验的人最有价值。

    README 原文

    未翻译

    Gaussian-Splat-Lite

    npm version CI License

    Three.js Gaussian Splatting · WebGPU · Streaming

    High performance 3D Gaussian Splatting (3DGS) renderer for Three.js with WebGPU/WebGL2. Supports PLY, SPZ, SOG, and RAD files, with streaming LOD for RAD, SOG, and LCC2 scenes.

    Try Live Demo

    Features

    FocusWhat you get
    WebGPU / WebGL2Use the same Three.js scene API with either renderer
    Large-scene streamingLoad RAD, SOG, and LCC2 detail as the camera moves, with smooth transitions
    Stochastic renderingOptional transparency mode, with an experimental neural denoiser to smooth it
    Offscreen captureRender Splats to images, cube maps, and environment maps for reflections
    SDF editsRecolor or hide parts of a model without moving Splats
    Data and precisionLoad URLs, files, or bytes; place local models in large GIS/ECEF scenes

    Installation

    npm install gaussian-splat-lite three
    

    Requires Three.js >=0.187.0.

    Quick start

    SplatMesh is a scene object. Add one GaussianSplatRenderer to display all visible Splat models in the scene.

    WebGPU

    import * as THREE from "three";
    import { WebGPURenderer } from "three/webgpu";
    import { GaussianSplatRenderer, SplatMesh } from "gaussian-splat-lite";
    
    const renderer = new WebGPURenderer({ antialias: false });
    await renderer.init(); // Initialize before constructing GaussianSplatRenderer.
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);
    
    const scene = new THREE.Scene();
    const camera = new THREE.PerspectiveCamera(
      60, window.innerWidth / window.innerHeight, 0.1, 1000,
    );
    camera.position.set(0, 0, 3);
    
    const splatRenderer = new GaussianSplatRenderer({
      renderer,
    });
    scene.add(splatRenderer);
    
    const splat = new SplatMesh({ url: "/assets/scene.spz" });
    scene.add(splat);
    await splat.initialized;
    
    renderer.setAnimationLoop(() => renderer.render(scene, camera));
    window.addEventListener("resize", () => {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
    });
    

    WebGL2

    WebGPURenderer automatically falls back to its WebGL2 backend when WebGPU is unavailable. To choose WebGL2 explicitly:

    const renderer = new WebGPURenderer({ antialias: false, forceWebGL: true });
    await renderer.init();
    

    For the classic WebGL renderer, replace the WebGPU renderer creation and initialization with:

    const renderer = new THREE.WebGLRenderer({ antialias: false });
    

    Keep the rest of the example unchanged.

    Stochastic rendering

    Sorted alpha blending is the default. To enable stochastic rendering:

    splatRenderer.stochastic = true;
    

    This mode produces visible noise. Smooth it with the experimental neural denoiser, which supports WebGPU and WebGL2, including WebXR. See Stochastic rendering for setup and requirements.

    Streaming large scenes

    Use RadStreamScheduler for RAD scenes with levels of detail (LOD), SogStreamScheduler for SOG lod-meta.json scenes, or Lcc2StreamScheduler for .lcc2 scenes. All three load detail as the camera moves and work on WebGPU and WebGL2.

    All three schedulers start empty. Add inputs with addSource() and remove them by their stable source ID with removeSource(id). The addition promise waits for metadata, not rendered data.

    For RAD, replace the SplatMesh loading and animation loop in the quick start with:

    import { RadStreamScheduler } from "gaussian-splat-lite";
    
    const streaming = new RadStreamScheduler({
      splatBudget: 3_000_000,
      fadeDurationMs: 200, // Smooth LOD transitions (default).
    });
    scene.add(streaming.group);
    streaming.setCamera(camera);
    streaming.setResolutionFromRenderer(camera, renderer); // CSS pixels; again after resizing.
    const sourceId = await streaming.addSource({ url: "/assets/scene.rad" });
    
    renderer.setAnimationLoop(() => {
      streaming.update();
      renderer.render(scene, camera);
    });
    
    // The update loop must be running before awaiting the first visible data.
    await streaming.firstRenderable;
    
    // When removing the model:
    // streaming.dispose();
    // streaming.group.removeFromParent();
    

    For streamed SOG, create an empty scheduler and add each input with addSource(). Its promise waits for that input's metadata. Register the camera and update before rendering each frame; SOG detail follows distance, so it needs no resolution:

    import { SogStreamScheduler } from "gaussian-splat-lite";
    
    const streaming = new SogStreamScheduler({
      splatBudget: 3_000_000,
      fadeDurationMs: 200, // Smooth LOD transitions (default).
    });
    scene.add(streaming.group);
    streaming.setCamera(camera);
    const sourceId = await streaming.addSource({
      url: "/assets/scene/lod-meta.json",
    });
    
    renderer.setAnimationLoop(() => {
      streaming.update();
      renderer.render(scene, camera);
    });
    await streaming.firstRenderable;
    
    // Remove one input without rebuilding the scheduler:
    // streaming.removeSource(sourceId);
    

    For LCC2, use Lcc2StreamScheduler and a .lcc2 index URL with the same camera and update loop as SOG:

    import { Lcc2StreamScheduler } from "gaussian-splat-lite";
    
    const streaming = new Lcc2StreamScheduler({ splatBudget: 3_000_000 });
    scene.add(streaming.group);
    streaming.setCamera(camera);
    const sourceId = await streaming.addSource({ url: "/assets/scene/meta.lcc2" });
    

    Keep the index and its companion files together. See LCC2 streaming for options, multiple inputs, and supported scene data.

    Documentation

    Rendering

    Models

    Large scenes

    Development

    Requires Node.js 22.12 or later, Rust via rustup, and the wasm32-unknown-unknown target. build:wasm installs wasm-pack through Cargo if needed.

    npm ci
    npm run build:wasm
    npm run dev
    

    Open the URL printed by Vite (normally http://localhost:8080/) and drop a .ply, .spz, .sog, or .rad file into the viewer, choose a local file, or load one from an HTTP(S) URL. For LCC2, select or drop the scene folder containing .lcc2 and its companion files, or load its index URL. For split SOG, select or drop meta.json together with its .webp images; for split RAD, include the header and its .radc pages. Files are decoded locally. Choose WebGPU / WebGL2 / WebGPU · WebGL2 in the viewer to compare backends.

    See Contributing for validation commands. npm run build emits ESM, CommonJS, declarations, and source maps in dist/.

    Acknowledgements

    Gaussian Splat Lite uses Spark and SuperSplat as reference implementations.

    License

    Licensed under Apache 2.0. See NOTICE and third-party licenses for attribution.