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
- Sort all Gaussians by depth, back-to-front.
- For each, project 3D Gaussian to 2D screen Gaussian (tile-based).
- 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.