Three.js From Zero · Article s10-02

S10-02 Gaussian Splatting

Season 10 · Article 02

Gaussian Splatting in the Browser

Replace millions of triangles with millions of 3D Gaussians. Each: position + covariance + color + opacity. Project to screen, blend. Photoreal real-world capture rendering at 60fps.

1. What's a Gaussian splat?

A 3D Gaussian (blob). 14 parameters:

  • Position (x, y, z): where in space.
  • Covariance (symmetric 3×3, so 6 params): ellipsoid shape + orientation. Usually stored as scale(3) + rotation quaternion(4).
  • Opacity (1): how transparent.
  • Color (3): RGB. Often extended to spherical harmonics (48 params) for view-dependent color.

2. Rendering

  1. Sort all Gaussians by depth, back-to-front.
  2. For each, project 3D Gaussian to 2D screen Gaussian (tile-based).
  3. Rasterize with alpha blend.

Result: photo-real view synthesis, no explicit mesh, captures fuzzy/transparent/fur perfectly.

3. The input

Train from 20-100 photos of a scene. Photogrammetry + gradient descent on Gaussians = "scene representation." Takes minutes on RTX, seconds for inference.

4. File formats

  • .splat: Luma's compact format. ~12 bytes/splat.
  • .ply: original research format, large.
  • .ksplat: Babylon's compressed variant.

5. Libraries

  • luma-web: Luma's viewer, one-liner.
  • @mkkellogg/gaussian-splats-3d: Three.js integration, MIT.
  • gsplat.js: minimal, educational.
  • spark.js: fast WebGPU renderer.

6. Three.js integration

import { Viewer } from '@mkkellogg/gaussian-splats-3d';

const viewer = new Viewer({
  'cameraUp': [0, -1, -0.6],
  'initialCameraPosition': [0, 0, 5],
  'initialCameraLookAt': [0, 0, 0],
});

await viewer.addSplatScene('/path/to/scene.splat');
viewer.start();

Or use Luma's hosted viewer: paste an iframe, done.

7. Live demo

A synthesized demo showing "what a splat renders like". A real splat needs an actual trained scene file — grab one from Luma AI's captures.

synthetic splat demo
This demo synthesizes a pseudo-splat effect from many transparent billboards. For real Gaussian Splatting, use the libraries listed above with .splat files from Luma, Postshot, or Polycam.

8. Perf knobs

  • Splat count: 100k-5M typical. Mobile caps ~500k.
  • Sort frequency: every frame ideal, every 10 frames acceptable.
  • Tile size: 16×16 standard.
  • Spherical harmonics: disable level 2-3 to save bandwidth.

9. When splats win vs meshes

Real-world scan (room, object)✅ splats
Character skinned animation❌ splats (no skinning yet)
Fine geometry (hard edges)❌ splats (softer)
Fuzzy / furry things✅ splats (native)
Lots of scale range✅ splats
Interactive gameplay collision❌ splats (no collision)

10. Takeaways

  • Gaussians are fuzzy 3D ellipsoids with color.
  • Train from photos. Render by sorting + projecting.
  • Replaced NeRF for speed. Real-time 60fps in browser.
  • .splat format, 12 bytes/splat.
  • @mkkellogg/gaussian-splats-3d for Three.js integration.
  • Use for real-world capture. Not for animated characters.