Skip to main content

How to View and Embed Gaussian Splatting on the Web

Updated Mar 2026

Gaussian Splatting has gone from an academic curiosity to a practical tool in under two years — and the browser is now a first-class deployment target. A typical outdoor scene captured with Polycam or Scaniverse clocks in between 80 MB and 400 MB as a raw PLY, but modern web viewers load and render these at 60 fps on a mid-range laptop. The trick is understanding what each viewer actually does with your data. There are four main approaches to 3DGS on the web right now: 1. **Privacy-first local viewers** like polyvia3d process the entire file inside the browser with WebGL/WebGPU — nothing ever leaves your machine. A 120 MB PLY loads in roughly 3–5 seconds on a 2022 MacBook Pro. 2. **Embeddable JS libraries** like gsplat.js (~180 KB gzipped) and antimatter15/splat give you full control over the render loop and let you integrate 3DGS into any Three.js or Babylon.js scene. 3. **Hosted platforms** like PlayCanvas SuperSplat stream splats from their CDN and offer no-code embedding with a single `<iframe>`. Fast to deploy, but your file lives on their servers. 4. **WebGPU-native renderers** are emerging fast — Mip-Splatting, 2DGS, and compressed formats like SPZ all have experimental web implementations. Choosing the wrong approach burns you in obvious ways: a 350 MB PLY embedded via iframe on a shared CDN will time out for mobile users. Conversely, a JS library drop-in is overkill when you just want visitors to view a single scan. This guide walks through each option with realistic expectations, then shows you exactly how to implement the two most common patterns: iframe embed and gsplat.js integration. Mobile is the hidden constraint. WebGL Gaussian Splatting works on iOS Safari 16+ and Chrome Android 115+, but frame rates drop to 20–30 fps on older devices at full splat counts. The section on performance optimisation covers the practical knobs: splat count culling, poster images for perceived load, and the SPZ format (10× smaller than PLY) for bandwidth-constrained deployments.

Tools used in this guide

Step-by-Step Guide

  1. 1

    Understand Your Viewer Options

    Before picking a viewer, measure your file. Open your PLY or SPLAT file in polyvia3d's PLY Gaussian Viewer at /splat-viewer/ply to get the splat count and estimated render weight — a scene with more than 3 million splats will struggle on mobile regardless of viewer. The four main options by use case: **polyvia3d** for privacy-sensitive or offline scenarios (zero upload, runs in your browser tab); **gsplat.js** when you need to integrate 3DGS into an existing Three.js application (npm install gsplat, ~180 KB bundle overhead); **antimatter15/splat** for minimal-dependency implementations (single JS file, no build step); **SuperSplat by PlayCanvas** when you want a hosted no-code solution and don't mind your file living on their CDN. If you're undecided, start with polyvia3d for validation — it supports PLY, SPZ, SPLAT, and KSplat formats natively.

  2. 2

    Optimise Your Splat File Before Embedding

    Raw PLY exports from training tools (3D Gaussian Splatting original, nerfstudio, gsplat library) are uncompressed and large. A garden scene trained for 30K iterations typically produces a 150–300 MB PLY. Before embedding, convert to a compressed format. SPZ (Niantic/Scaniverse format) achieves 8–12× compression with minimal visible quality loss — a 200 MB PLY commonly compresses to 18–22 MB SPZ. Use polyvia3d's PLY to SPZ converter at /splat-convert/ply-to-spz directly in your browser. SPLAT format (antimatter15) offers 4–6× compression with faster decode but wider compatibility. KSplat adds level-of-detail on top, which helps for scenes above 2 million splats. Rule of thumb: keep your embedded file under 30 MB for a sub-3-second load on a typical broadband connection (25 Mbps).

  3. 3

    Embed via iframe (Hosted Platform Approach)

    The fastest path to embedding is hosting your splat on a platform that provides an iframe snippet. Upload your file to SuperSplat (playcanvas.com/supersplat) or Luma AI, then copy their embed code. A typical SuperSplat iframe looks like: `<iframe src="https://supersplat.playcanvas.com/viewer/?url=YOUR_FILE_URL" width="100%" height="500" frameborder="0" allow="fullscreen"></iframe>`. Key attributes to set: `allow="fullscreen"` for immersive viewing; a fixed `height` of 400–600 px for desktop layouts; `loading="lazy"` to defer loading below the fold. Downsides: you depend on the host's uptime, you can't customise renderer behaviour, and file size is constrained by the platform's upload limits (SuperSplat free tier: 200 MB). Always include a static poster image as a fallback for users whose browsers block iframes.

  4. 4

    Integrate gsplat.js Into Your Own Site

    For full control, use gsplat.js. Install via npm: `npm install gsplat`. The minimal setup loads a splat and renders it into a canvas element in about 15 lines of code. Import `Scene`, `Renderer`, and `Camera` from the package; create a renderer targeting your `<canvas id="canvas">`; call `scene.loadFromURL("/your-scene.spz")` (gsplat.js supports PLY, SPLAT, and SPZ natively); then start the render loop with `renderer.render(scene, camera)` in a `requestAnimationFrame` callback. Performance tip: set `renderer.setSize(window.innerWidth, window.innerHeight)` once on load and listen for resize events rather than reading it on every frame — this alone saves ~2 ms per frame on complex scenes.

  5. 5

    Add a Poster Image for Perceived Performance

    Regardless of viewer, always render a static poster image — a WebP screenshot of your splat at 1200×630 px. This serves three purposes: it gives users something to look at during the 2–5 second load; it acts as the Open Graph image for link previews; and it gives search engines image content to index (3DGS files themselves are not crawlable). Generate the poster by opening your splat in polyvia3d's viewer, framing the best angle, and using the browser's screenshot tool (F12 → device toolbar → screenshot, or a browser extension). Serve the poster as a `<img>` behind the canvas element with `z-index: -1` so it disappears the moment the 3D scene renders. This pattern cuts perceived load time by 40–60% in user testing.

  6. 6

    Optimise for Mobile

    Mobile is where 3DGS embeds fail most often. iPhones from 2020 onwards handle 1–2 million splats at 30 fps; Android midrange (Snapdragon 7xx) is similar. Above that, frame rates drop to single digits. Strategies: (1) Reduce splat count — re-export from your training tool at a lower iteration count (15K instead of 30K) for a mobile-targeted version; a 15K iteration garden scene typically has 800K splats vs 2.2M at 30K. (2) Use SPZ — smaller file means faster initial load, which matters more on mobile where the user may not wait. (3) Detect GPU tier at runtime using the WebGL renderer info (`gl.getParameter(gl.RENDERER)`) and load a lower-count variant for mobile. (4) Set a pixel ratio cap: `renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5))` — this alone recovers 25–30% frame time on high-DPI mobile screens.

  7. 7

    Test Across Browsers and Validate Load Times

    Test your embed in Chrome 120+, Safari 16.4+, and Firefox 121+ before going live. Safari historically had the most issues with large TypedArray allocations (used internally by splat renderers) — this was largely fixed in Safari 16.4. Use Chrome DevTools Network tab with throttling set to "Fast 3G" to simulate the real-world load experience for mobile users: a 25 MB SPZ file should appear loaded within 8 seconds on Fast 3G, versus under 2 seconds on broadband. If your file takes longer, either reduce it further or implement progressive loading — some viewers (including gsplat.js) support streaming PLY that renders splats as they download. Check the browser console for WebGL context lost events, which indicate GPU memory pressure and suggest your splat count is too high for the target device.

Frequently Asked Questions

Which Gaussian Splatting web viewer has the best mobile support?
gsplat.js and SuperSplat both have reasonable mobile support, but for the best results reduce your splat count to under 1 million before targeting mobile. polyvia3d's viewer works on iOS Safari 16.4+ and Chrome Android for local file inspection, though it's not designed for embedding.
What file format should I use for web embedding?
SPZ for minimum file size (8–12× smaller than PLY) with good quality. SPLAT format for maximum compatibility across different viewers. KSplat if you need level-of-detail and are using gsplat.js. Avoid raw PLY for production embeds — file sizes are typically 10× larger than necessary.
Can I embed a Gaussian Splatting scene without hosting the file myself?
Yes. PlayCanvas SuperSplat, Luma AI, and Polycam all offer hosted embedding with iframe snippets. SuperSplat's free tier supports files up to 200 MB. The trade-off is that you depend on their availability and can't customise the viewer appearance.
Does Gaussian Splatting work in WebGPU?
Yes, and it's significantly faster. WebGPU Gaussian Splatting implementations (like those using the WebGPU backend in gsplat.js or custom WGSL shaders) can achieve 2–3× the splat count at the same frame rate compared to WebGL. Browser support as of early 2026: Chrome 113+, Edge 113+, Safari 18+, Firefox 141+. All major browsers now support WebGPU.
How do I prevent my 3DGS embed from freezing the browser tab?
The most common cause is an oversized PLY file (>100 MB) loading synchronously. Switch to SPZ format, implement lazy loading (only start loading when the canvas enters the viewport using IntersectionObserver), and set a splat count cap of 2 million for desktop and 800K for mobile.

Related Tools

Related Format Guides