How to Build a Gaussian Splat Viewer PWA in One Day (From Capture to Deploy)

Step-by-step: capture a real-world scene, generate a Gaussian Splat model, and deploy a progressive web app viewer to share it—all within a day.

All posts

TL;DR

  • You'll build: a web-based 3D viewer (PWA) that displays a photorealistic scene reconstructed from a set of photos (using Gaussian Splatting).
  • you'll do: 1. Collect a real world scene 2. Make 3D gaussian splat model 3. View it with open source tools 4. Turn into a Progressive Web App 5. Try on iPhone and Android What
  • you'll need: 1. PlayCanvas account (free) to use the Supersplat tool. 2. Smartphone/camera to capture photos (or a sample dataset) 3. Laptop and a modern web browser (chrome 115+, safari 16+, etc.)

1) What is Gaussian Splatting?

What it enables

  • Photorealistic 3D from images: Gaussian Splatting is a cutting-edge technique that takes a set of ordinary photographs and generates a navigable 3D scene out of them. It produces point cloud-like "splats" (tiny translucent 3D blobs) that collectively reconstruct the scene with realistic detail.
  • Real-time rendering in browser: Unlike earlier Neural Radiance Field (NeRF) methods that required heavy computation, Gaussian Splat models can be rendered very efficiently on standard GPUs. This means you can explore the 3D scene in a web browser at interactive frame rates, even on consumer devices.
  • Easy sharing and embedding: Because the output can be just a collection of points (often stored in a .ply file) and a lightweight viewer, it's easy to package and share. Tools like SuperSplat allow exporting a single HTML file viewer for a model, and even one-click publishing to a URL, so anyone can view your 3D capture without installing special apps.

When to use it

  • Reality capture & virtual tours: Use Gaussian Splatting when you want to turn real-world environments (rooms, buildings, outdoor scenes) or objects into photorealistic 3D models quickly. It's ideal for scenarios like real estate virtual tours, construction site capture, cultural heritage digitization, or museum exhibits – anywhere you need a realistic 3D "clone" of a place or object.
  • Product visualization: For e-commerce or marketing, Gaussian Splats can capture retail products or artifacts in rich detail. They allow users to view items from all angles with realism. For example, the Reflct platform uses 3DGS for product showcases, letting creators set up predefined views for shoppers.
  • Rapid prototyping and demos: If you have limited time or resources to create a full 3D model by hand, this technique shines. In hackathons or prototyping sessions, you can capture a space in the morning and have an interactive demo by evening. The entire pipeline from photos to a shareable 3D web app can be done in under a day.

Current limitations

  • Capture requirements: The quality of the result heavily depends on the photo capture process. You need good coverage of the subject with carefully taken images. Too many images can introduce noise. Texture-less areas (like plain white walls) can cause holes or alignment issues. Using a decent camera (or carefully taken smartphone photos with consistent settings) is recommended for best results.
  • Device & browser support: While the viewer can run on the web, certain implementations use newer tech like WebGPU (e.g. some open-source viewers) that require up-to-date browsers and hardware. For example, one WebGPU-based viewer needs Chrome/Edge 115+ or special flags on Linux. The good news is other viewers use WebGL for broader compatibility, but very large models might still struggle on older mobile devices due to memory or GPU limits.
  • No dynamic lighting or editing: These splat-based scenes are more like captured snapshots of reality. You cannot easily relight the scene or alter geometry after the fact (unlike traditional 3D models). The splats carry baked color (often even baked illumination). Advanced features like dynamic shadows or fine geometry editing aren't natively supported yet. Also, view-dependent effects (like shiny reflections via spherical harmonics) are usually omitted to keep file size manageable. In short, it looks great as-is, but it's not as flexible as a hand-crafted 3D model.
  • Emerging ecosystem: Gaussian Splatting is a very new technique (circa 2023), so tooling is evolving. File sizes can be large (point clouds with millions of points), though new compression formats like SOG (Sparse Occupancy Grid Splat, dubbed the "WebP of Gaussian Splatting") are being developed to shrink files dramatically. Expect rapid changes; what works today (often in "preview" or beta form) will improve quickly. Always check the latest tools and browser updates if you hit a roadblock.

2) Prerequisites

Access requirements

  • PlayCanvas account (create/login into PlayCanvas Developer Portal (it's free)) This is going to be used for SuperSplat which is online tool for editing/publishing your splat model (if you don't want to use it, you can use open source tools, but we will refer to it to quickly publish).
  • (Optional) GitHub access: If you plan to use open-source code like the Spark renderer or Kevin Kwok's Splat viewer, you might clone those repositories. No special permission needed, but familiarity with downloading/cloning from GitHub is assumed.
  • Project/app registration: Not strictly needed for the web approach (no API keys required). If using an alternate platform's service (e.g., DJI Terra or Luma AI for generating the model), you'd need accounts for those, but in this guide we focus on open solutions.

Platform setup

iOS (for PWA testing)

  • Safari (iOS 16+): Ensure your iPhone/iPad has Safari updated. iOS Safari supports WebGL out of the box; WebGPU support is experimental as of 2025, so our viewer will stick to WebGL for compatibility reasons. A physical iPhone is recommended to test the PWA's AR mode (since Safari's WebXR is limited, we'll note an alternative for AR).
  • PWA Install method: Know how to add a webpage to your Home Screen on iOS (Safari's "Add to Home Screen" option) because iOS won't show an install prompt. This gives the full-screen app-like experience for your viewer.
  • (No Xcode or native SDK needed) – We're building a web app, so no need for Xcode or CocoaPods. Just have a way to transfer sample data to your device if needed (AirDrop, iCloud, etc., in case you want the PLY file on device, though not necessary).

Android (for PWA testing)

  • Chrome or Edge (Android 115+): Use the latest Chrome (or any Chromium browser) on Android. Chrome supports PWA installation and WebXR AR features. A physical Android phone (with ARCore support if you plan to use AR) is recommended.
  • "Install App" prompt enabled: Visit chrome://flags and ensure the PWA install prompt is enabled (usually default). This will let you easily install the viewer PWA by tapping the Install banner or via menu.
  • (No Android Studio or native code needed) – Everything runs via the browser. Just ensure your device can load large web content and you have a way to host or access the PWA link (we will also cover simple local hosting options).

Development machine

  • Laptop/PC with WebGL-capable browser: For the capture processing and integration steps, use a desktop or laptop with a modern browser. Chrome, Firefox, or Edge are fine for general use; Chrome/Edge are needed if using WebGPU-based tools. Ensure your GPU drivers are up-to-date.
  • Python and/or Node.js (optional): If you want to run open-source pipelines (like NerfStudio for training, or Python scripts to convert data) or to set up a local web server for the PWA, having Python 3 or Node.js could be useful. Strictly not necessary if you only use only GUI tools and hosting platform given but it's helpful if you play around with scripts.
  • Camera or drone for capture: For the "capture" part, a smartphone with a decent camera can work. However, for best results, a DSLR or mirrorless camera gives you more control (manual exposure, etc.). If using a drone for outdoor scenes, ensure you can transfer images to your PC. If you don't have any camera available, you can use sample images or a pre-made sample model provided in this guide.

Hardware or mock

  • Scene to capture or sample data: Identify a scene or object you want to capture (e.g., your backyard, a room, a statue). If you don't, you can download one of the sample gaussian splat model. The original authors of the GS have the example outputs (ply+camera files) that you can refer to. Tripod or
  • stable platform for capturing (if possible): To avoid motion blur in the photos, it's better if you can either have a tripod or be steady in your hands during photography. If you have a lot of blurry/misaligned photos, it might affect the reconstruction.
  • Good lighting or controlled environment: Try to capture under consistent lighting (avoid moving shadows or changing light between shots). Uneven lighting can introduce artifacts in the 3D result.
  • No need for any fancy wearable/mock: unlike some AR tutorials, we don't need to connect to a separate wearable thing. The 'wearable' thing here is basically the phone you use to view AR. So if you don't have a phone with AR, you can still do everything else except the AR view.

3) Get Access to Gaussian Splatting Tools

  1. Access the editor: Go to the SuperSplat Editor (PlayCanvas's online Gaussian Splat tool). Log in with your PlayCanvas account (sign up free if you don't have one). This web-based editor runs in your browser.
  2. Request any beta features: Currently, SuperSplat is open to all, no special beta flags needed. (If the platform had a private beta, this is where you'd ensure your account is enabled. For example, if you opted to use DJI Terra or Luma AI's Gaussian splatting, you'd ensure your account has that feature enabled – but with SuperSplat, everything is available by default.)
  3. Create a project (if needed): In SuperSplat, you work with .ply files directly rather than creating a "cloud project". However, if you use the PlayCanvas Editor route later, you might create a PlayCanvas project for a full application. For now, just open the SuperSplat web app; no project creation is required to get started.
  4. Prepare the capture pipeline: Decide how you will generate the Gaussian Splat model from your photos:
    • Option A (Beginner-friendly): Use an all-in-one tool like Luma AI or XGRIDS Lixel (if you have access) that can output a NeRF or point cloud model. Then convert that to a Gaussian splat if needed. DJI's Terra software, for example, added Gaussian splatting export for drone imagery. This may involve uploading photos and downloading a PLY.
    • Option B (Open-source): Use NerfStudio or the official Inria Gaussian Splatting code. NerfStudio (open source) can train a NeRF and has a script to convert to a Gaussian splat point cloud (via ns-process-data command, as noted in the OpenSplat project). The official code from the paper can also output a PLY after training. These require a machine with a decent NVIDIA GPU (for training) and some comfort with Python. If you go this route, set up the environment (install NerfStudio, etc.) and be ready to run training on your images.
    • Option C: Skip training with a sample model. To follow this tutorial first, you can use pre-generated sample data. For instance, PlayCanvas provides an example PLY if you don't have one at hand (look for the "here's an example" link on their blog). Download that .ply file to use in the next steps.
  5. Download credentials or tools: Most Gaussian splat viewers don't require API keys, but gather these items:
    • SuperSplat PWA (optional): While on the SuperSplat Editor page, you can install it as a PWA (in Chrome/Edge, look for the install icon). This isn't mandatory, but it can associate PLY files on your system to open with it.
    • Conversion scripts: If your pipeline requires converting outputs, download those. For example, Kevin Kwok's splat tool has a convert.py script to turn a NeRF's output into their .splat format. PlayCanvas introduced SplatTransform CLI which can convert and compress PLY to their optimized format (SOG) – you can get it from their GitHub if needed.
    • App IDs/tokens: Not applicable here since our viewer will be static. If embedding in an existing site, no special API token is needed – it's all client-side. (If using a cloud hosting or API for AR, you'd note credentials here, but in our case, publishing via SuperSplat or self-hosting covers it.)

Done when: you have at least one 3D Gaussian Splat model (or the data to create it) ready to use. This means either:

  • A .ply file and (optionally) a cameras.json from your scene (common output from the GS pipeline) – for example scene.ply plus camera data.
  • Or a specialized .splat file (if using the spark/antimatter viewer) – you can always convert .ply to .splat in the viewer later by drag-and-drop.
  • And you have access to the SuperSplat tool or the equivalent viewer to load this model. You should be logged in to the SuperSplat editor if you plan to publish through it.

4) Quickstart A — Run the Sample App (iOS)

Goal

Run a Gaussian Splat viewer as a PWA on an iPhone (or iPad) to verify that your captured model can be viewed interactively, and test basic features like navigation and AR. We will use the official SuperSplat sample viewer for simplicity, loading our model into it on iOS Safari.

Step 1 — Get the sample viewer

  • Use SuperSplat's web viewer: On your iPhone, open Safari and navigate to superspl.at/editor (the SuperSplat editor) or the PlayCanvas Statue Project example which is a live 3DGS scene. This is a fully functional viewer in the browser.
  • Alternative – static viewer: You can also use Kevin Kwok's WebGL viewer directly by visiting antimatter15.com/splat/ on your iPhone. It will load a default scene. (This viewer is more minimal, but doesn't require login.)
  • Download PWA (optional): If you see an install banner or plus icon in Safari, use "Add to Home Screen". On iOS, visit the share menu and tap Add to Home Screen to save the page as an app. (SuperSplat is a PWA, but Safari might not automatically prompt; this manual step makes it behave like an installed app.)

Step 2 — Load your 3D model

  • Open or import the PLY: In SuperSplat Editor (on iOS Safari), tap File → Import and select your .ply file. You might need to have the file in iCloud Drive or a location Safari can access. Once selected, the model will load in the viewer. (Large files might take a minute to parse – be patient.)
  • (If using antimatter15 viewer): That viewer lets you drag-and-drop a file into the page, but mobile Safari doesn't support drag-drop. Instead, you can upload your PLY to a web-accessible URL (with CORS enabled) and append ?url=YOURMODELURL.ply to the viewer URL to load it. For a quick test, you might skip this on mobile due to complexity and use the default sample; you can always test your own model on desktop and then just view the published version on iOS later.

Step 3 — Configure viewer settings

  • Adjust quality/performance: In SuperSplat's menu (if visible on mobile, you might need to rotate or use two-finger swipe to scroll the UI), you can toggle settings like point size or performance vs quality. For now, use defaults. The PlayCanvas engine powering it is optimized to handle millions of splats smoothly.
  • Enable AR (if available): SuperSplat's viewer has an AR button (usually an icon of a cube or AR headset) if the device/browser supports WebXR AR. On iOS Safari, WebXR augmented reality is not fully supported (Safari doesn't yet implement AR session). However, Safari does support an older Quick Look AR for USDZ models, which isn't directly applicable here. So on iPhone, you might not see an AR button. That's expected – we'll test AR on Android in Quickstart B.
  • Permissions: The viewer doesn't need any special permissions just to display the model. Audio/microphone aren't used here, and camera would only be used for AR (which on iOS Safari isn't active). So no permission prompts should appear in this step.

Step 4 — Run and explore

  1. Navigate the scene: Use standard gestures – one finger drag to orbit around, two-finger pinch to zoom, two-finger pan to shift view (these are supported in the viewer). Try moving around your splat model. On-screen controls might also be available (e.g., a joystick or arrow pad) depending on the UI.
  2. Test installation: If you added to Home Screen, close Safari and launch the app from your home screen. It should open full-screen, with no browser UI. Confirm that it loads your model (you might need to import the file again within the PWA on first run). Once loaded, it should stay in state if you leave and come back.
  3. Save a view (optional): In some viewers like antimatter15's, pressing "v" on desktop saves the current view to the URL. On mobile you might not have a keyboard, but this isn't crucial. Just note that the viewer can encode camera positions if needed.

Step 5 — (Optional) Connect to AR display

iOS currently doesn't support WebXR-based AR in browser, so this step is more of a placeholder. If you have access to an Apple Vision Pro (which supports WebXR in visionOS Safari) or want to simulate AR, you can:

  • Use a tool like Reality Composer to place a dummy object in AR, or
  • Simply skip AR on iOS. We'll do AR on Android in the next section, which has broad support.

If you were on an AR-supported iOS app, at this step you'd grant camera access for AR and see the 3D model anchored in your environment. Since that's not applicable, ensure everything else works (model renders and you can interact) on iOS.

Verify

  • Model renders correctly: You should see a point-cloud or splat representation of the scene. Colors and basic shapes should look photorealistic from the original photos. If you used a sample, check that it resembles the expected scene (e.g., the provided sample might be a bike or a statue – confirm you see that).
  • Performance is acceptable: Rotate and move around. On an iPhone, you ideally get ~30fps or more. If it's choppy, the model might be very large. SuperSplat uses the optimized PlayCanvas engine which handles millions of splats at smooth frame rates, so it should be okay. Minor lag during initial loading is normal.
  • PWA works offline (if installed): Turn on airplane mode and open the PWA from home screen (only do this after it's fully loaded once). It might still show the model if the viewer code and model file are cached. If not, don't worry – we haven't set up full offline caching of the model. The viewer app itself should open, but it may need internet if the model wasn't cached. (Full offline support would require a service worker caching the PLY, which is an advanced step beyond this quickstart.)

Common issues

  • Black screen or model doesn't appear Just a black view? Perhaps a safari/webgl oddity. Try tapping the AR or VR toggle then back (if visible) or ensure that "WebGL via Metal" is enabled in Safari experimental settings. Make sure it has loaded the file first. Sometimes mobile safari won't load big files on low memory.
  • "Unsupported file" Error: If SuperSplat says the PLY can't be opened, it might be due to format. It could be format related. Make sure you are using a ply file from gaussian splat pipeline. (ie. with per point color (and maybe normals)) If you have.splat file, keep in mind that SuperSplat is expecting a PLY file. You'll need to convert it back or use another viewer.
  • Low performance on older iPhone: If you're on an older iPhone (ex. iPhone X or below). The number of points could be too much. Maybe try a decimated model (ie. less points) or if the viewer supports it, try a point budget mode to reduce the number of drawn splats. Maybe make sure you're not running any other heavy apps.
  • App not installing on home screen: If "Add to Home Screen" isn't available, double-check you're not in private browsing and that the site has a valid SSL (it should). SuperSplat is HTTPS, so it should allow PWA install. iOS might also require at least one interaction before showing the option.

5) Quickstart B — Run the Sample App (Android)

Goal

Run the Gaussian Splat viewer on an Android device, and test the augmented reality mode with a supported device. Android's Chrome browser supports WebXR, meaning we can actually view the 3D splat in AR through the camera. We'll also verify the PWA installation and performance on Android.

Step 1 — Get the sample viewer

  • Open viewer in Chrome: On your Android phone, navigate to the same viewer used in Quickstart A. For example, open superspl.at/editor in Chrome. Alternatively, a dedicated sample app: you could use the PlayCanvas Statue Project link or any published splat URL from SuperSplat (if you published your own in section 3).
  • Install the PWA: Chrome will typically show an "Install" button in the URL bar if it recognizes the site as a PWA. Tap that to install the viewer app. (If you don't see it, open Chrome's menu ⋮ and tap "Install App".) In a second, it will add an icon to your launcher for the SuperSplat Editor or your specific app link.
  • Launch the installed app: Tap the new icon to launch the viewer in full-screen mode, just like a native app. This ensures we have the PWA environment ready for AR (some WebXR features work better in installed PWAs on Android).

Step 2 — Configure dependencies (Android-specific)

(Most configuration is already done by the web app, but a few Android specifics:)

  • Enable camera permission for AR: The first time you invoke AR mode, Chrome will ask for camera access. Be prepared to grant it. You can also preemptively check in Android Settings -> Apps -> Chrome -> Permissions that Camera is allowed.
  • ARCore installation: For WebXR AR to work, your device needs Google Play Services for AR (ARCore). Most modern Android phones have it by default. If not, install Google AR Services from the Play Store. Without ARCore, the AR button may not appear at all in the viewer.
  • Background audio (if any): Our app doesn't use audio, but note that PWA on Android could continue running in background or after screen off differently than iOS. No special changes needed for us, just something to be aware of if you had a long-running process.

Step 3 — Configure app (permissions & settings)

  • Load your model: In the PWA viewer (should be the same interface as in Quickstart A), load your .ply model if you haven't already. If you published your model to a URL via SuperSplat in Step 3, simply navigate to that URL in Chrome and install it from there; then your model will load automatically. (Publishing gave you a unique link to your model's viewer).
  • Add required permissions in WebXR: Chrome will handle this when you tap AR. There's no manifest like AndroidManifest.xml for us to edit in a PWA context, but ensure:
    • Camera: allowed (as above).
    • Motion sensors: for AR/VR, Chrome might ask for gyroscope/accelerometer permission (some devices do). Grant if prompted.
  • Optimize for mobile: Some viewers (Spark or three.js based ones) might allow setting an XRSession required features. SuperSplat is already configured. If you were coding your own viewer, you'd ensure requiredFeatures: ['hit-test', 'dom-overlay'] etc. are set for AR. With the off-the-shelf viewer, no changes needed from our side.

Step 4 — Run on Android device

  1. Test navigation: Use touch controls to orbit and zoom around your scene in the Android PWA, just as you did on iOS. Verify it's smooth. Android devices vary, but a modern phone with Chrome and a decent GPU should handle millions of points easily, similar to desktop.
  2. Enter AR mode: Tap the AR headset icon or AR button in the viewer. Chrome will likely prompt "Allow access to camera for AR?" – grant it. Then your camera will open, and you'll see a prompt to move your device to scan the environment (this is ARCore establishing tracking).
  3. Place the model: After a moment, the 3D model should appear overlaid on the real world through your camera feed! By default, it may appear in front of you at some default scale. Physically move and rotate your phone to see the model from different angles. You can usually tap on a surface to reposition the model, or pinch to scale, depending on how the viewer implemented AR (the PlayCanvas viewer likely places it at a fixed real-world size and uses plane detection).
  4. Exit AR: Use the on-screen X or back button to leave AR mode and return to the normal 3D view. The model should still be loaded in the app, unchanged.

Step 5 — Connect to wearable/mock (VR headset)

Android also supports VR through WebXR. If you have a Meta Quest or another headset that can use the Android browser or an WebXR viewer, you could test VR mode:

  • Pair/connect your headset or use Oculus Browser on Quest to navigate to the same URL. You might need to enable developer mode or use an emulator if you want to simulate this on PC.
  • For our purposes, testing AR on a phone is usually enough. VR mode on phone (stereoscopic split) might be accessible if the viewer has a VR button. You could drop your phone into something like a Google Cardboard to experience the scene in VR. This is an optional stretch goal.

In summary, ensure at least one AR-capable device (likely an Android phone with ARCore) is tested so you know users can see the model in their space. This is one of the coolest features – being able to "spawn photorealistic 3D models directly into your environment" as the PlayCanvas team puts it.

Verify

  • AR mode works: After moving your phone around, the model should lock into the real world with reasonable stability. Check that it's oriented and scaled sensibly (you might find it floating or too large/small; some viewers use 1 unit = 1 meter, which can make a model of a small object appear giant if not adjusted).
  • No major lag or drift: The AR should update in real-time as you move (30fps or more). If it's very laggy, your phone might be struggling consider reducing point count or ensure no thermal throttling.
  • If tap to place is supported: So if you tap on a surface the model should reposition. See if that works. Not supported in all viewers but fairly common for arcore stuff. Could mean it places in a set location relative to initial place if not supported.
  • PWA integration: so open and close (or just close) the app from the launcher. See if it opens still offline. (assuming its cached) Could be that some webrx libs weren't cached that prevent you from starting the ar offline, but once installed should be pretty self-contained.

Common issues

  • Gradle auth error dependency not found: this is more for native android and not relevant for us in PWA scenario. We do not have gradle. If you are looking at integrating into native app via webview and a library, you may face dependency problems but not for our pure web scenario.
  • WebXR permission not persisting: Sometimes after first use, the camera permission might not stick in the PWA. If AR fails silently on second try, go to Android Settings -> Apps -> [Your PWA] and ensure Camera permission is granted (PWAs might appear as separate apps named after the site).
  • Device connection timeout (AR mode just shows you a black screen or "looking for surfaces" indefinitely) It might be an ARCore problem. Maybe try restarting the app, maybe move your device slower, or check if other apps can use ARCore (e.g., Google's Scene Viewer, AR in google search). Occasionally, you have to calibrate your phone for AR (wave your hand in figure 8 motion). No
  • install banner (Chrome didn't show you an install banner) Are you sure that you visited the site via HTTPS? And not in Incognito mode? You can always install it via menu, like said. Sometimes the site only shows you a prompt after user interaction (e.g., you click a button).
  • Browser fallback: If you use Firefox or a non-Chrome browser on Android, note that WebXR might not be supported (Firefox for Android doesn't support AR as of now). Stick to Chrome or a Chromium-based browser for AR features.

6) Integration Guide — Add Gaussian Splat Viewer to an Existing Web App

Goal

Integrate the Gaussian Splatting technology into your own website or web application. We'll take what we learned from the sample app and bring it into an existing project – for example, adding a "3D View" page in your company's web portal that shows a captured scene. The aim is to embed the 3DGS viewer (or library) into your app architecture and enable one end-to-end feature: displaying a splat model to your users, possibly with AR support.

Architecture

  • Your Web App UI → 3D Splat Viewer Component → Gaussian Splat model data (.ply/.splat). The viewer component (which could be built with Three.js + Spark, or an iframe to a viewer, or PlayCanvas Engine) takes the model data and renders it in a canvas element on your page. If using AR, the chain is: User clicks AR → WebXR session starts via browser → device camera & sensors provide background + tracking → the 3D content anchors into real world.
  • If you use an iframe embed (e.g., pointing to the superspl.at viewer with a URL param of your model), it's like: App -> iframe -> external viewer app. That's quick but less flexible. Alternatively, using a library gives you more control in-app.
  • We recommend using Spark (sparkjs.dev) or the PlayCanvas Engine for deep integration:
    • Spark (Three.js) – Spark is a Three.js-based renderer specifically for Gaussian Splats, with support for animations, multiple model formats, etc. It can be included as an npm package and you then use it like any Three.js component in your existing app.
    • PlayCanvas Engine – You can load the PlayCanvas 3DGS user guide and scripts, and then instantiate a viewer inside an existing page's canvas. This requires more setup (PlayCanvas engine setup, loading the splat material/shader).
  • Connection to AR/VR: If your app will have an AR button, the integration is between your UI and the browser's WebXR API. The viewer (Spark or PlayCanvas) must be set up to handle an XR session. PlayCanvas has built-in WebXR support; with Three.js (Spark) you use Three.js's WebXR manager.

Step 1 — Install the viewer SDK or library

For a web (JavaScript) project:

  • Add the Spark library. If available on npm, run: npm install @sparkjsdev/spark (or add via <script> from their CDN). Spark is MIT-licensed open source. Once included, you'll have classes to load a .splat or .ply file into a Three.js scene.
  • Alternatively, include antimatter15's viewer code. It's just a few files (one HTML, one JS, plus optional Python script). You might directly copy main.js and the shader code from that repo into your project, but Spark is a more packaged solution.
  • If using PlayCanvas Engine: include the PlayCanvas engine script (from their CDN or npm). Also get the 3D Gaussian Splatting User Manual/Script which likely includes the special material/shader to render splats. (PlayCanvas Editor users can simply upload PLY to the editor, but in code you need to mimic what the editor does.)
  • Ensure your build process (Webpack, etc.) includes these dependencies. Since Spark relies on Three.js, you need Three.js r150 or above as a peer dependency.

For a native app (optional scenario): If you were integrating into an iOS/Android app, you could skip that and simply embed a WebView that loads your web content with the above libraries. The heavy lifting stays in JavaScript. So no native SDK in that sense.

Step 2 — Add required permissions

Even on web, if you intend to use AR, you should handle permission flows gracefully:

In-browser (for WebXR via HTTPS):

  • The browser will request camera permission when starting an AR session. You can't change the prompt text via web, but you can prompt the user with a friendly UI beforehand ("Tap 'Allow' to enable AR camera view").
  • No need for a manifest entry like native apps, but ensure your site is on HTTPS (WebXR and camera access won't work on insecure origins).

If using an iframe embed: The iframe needs allow="camera; gyroscope; xr-spatial-tracking" attributes to enable AR sessions inside it. Make sure to set those or AR will be blocked.

If not using AR/VR, then no special permissions at all – viewing the 3D content itself doesn't require any permission.

Step 3 — Create a thin client wrapper in your app

To keep your integration clean, abstract the 3DGS functionality into a few components/services within your app code:

  • WearablesClient SplatViewerClient: This would manage connecting and loading the model. For instance, it can deal with initialization of Spark's renderer and reading.splat file and running the render loop etc. (the name "WearablesClient" was from the template, it can be SplatViewer or GSplatService here.)
  • FeatureService: if you want to have interactive features (switching viewpoints, triggering scene animation or measurement etc.), then wrap them. For instance, focusView(name) method to change camera to pre-defined viewpoint (like Reflct has curated views).
  • PermissionsService: Specifically for AR, this could check if AR is available (navigator.xr && navigator.xr.isSessionSupported('immersive-ar')), and handle prompting the user or falling back if not. It can also listen for the onvisibilitychange events of XR session to pause/resume rendering as needed.

Implementing these as classes/modules in your codebase will make it easier to maintain. For instance:



// Pseudo-structure

class SplatViewer {

constructor(container) { /* init Three.js or PlayCanvas in this DOM container / } loadModel(fileUrl) { / load .splat or .ply, set up scene / } startRendering() { / begin render loop / } enterAR() { / initiate WebXR AR session if supported / } exitAR() { / end session, return to normal view */ }

}

Definition of done:

  • The 3D viewer initializes as part of your app (e.g., when user navigates to the "3D view" page, the canvas appears and model is shown).
  • The system can handle connect/disconnect or loading/unloading gracefully. In web terms, this means if the user navigates away, you dispose of Three.js scenes or stop PlayCanvas to not leak memory. If they come back, you re-init if needed.
  • Errors (like "model file not found" or "WebGL not supported") are caught and displayed to the user in a friendly way. E.g., if someone's on an old browser with no WebGL, you detect that and show "Your device isn't supported" rather than a blank div.

Step 4 — Add a minimal UI screen

Design a simple UI in your app for the 3D viewer feature:

  • Canvas Display: A <canvas> or <div> element that will contain the 3D scene. Ensure it's styled to fill the screen or a designated area.
  • "View in AR" button: Visible on devices that support it (use PermissionsService to check). When clicked, call your SplatViewer.enterAR() to start the AR session. You might change the icon to indicate active AR and provide a way to exit (maybe the same button toggles AR off or a separate "Exit AR" appears).
  • Connection status/Loading indicator: If the model is loading (which could be a few seconds for a large PLY), show a spinner or progress bar. Once loaded, if applicable, show a "Connected" or ready state. (The concept of connect/disconnect is more for Bluetooth devices – here it might be "Model loaded" status).
  • Controls: At minimum, maybe a help tooltip explaining touch controls (e.g., "Drag to rotate, pinch to zoom"). If you have multiple scenes or models, a dropdown to switch models could be added (though not in our one-day scope).
  • If you have multiple viewpoints or an animation, add buttons for those ("Next View", "Play Tour", etc. – these would use the FeatureService to manipulate the camera or splats).

By the end of this integration, your existing app should be able to:

  • Load a page where the user can see the 3D model inside your UI chrome.
  • Let the user interact with it (rotate/zoom).
  • Optionally enter AR mode to see it in their environment.
  • Close the view and return to the rest of your app seamlessly.

7) Feature Recipe — View Your Splat in Augmented Reality (AR)

Goal

Enable a one-click "View in AR" feature in your Gaussian Splat viewer. When the user taps an AR button, the web app will overlay the 3D splat model onto the real world through the device camera. This recipe covers the user flow, implementation steps, and common pitfalls for AR integration.

UX flow

  1. Pre-check: The app determines if AR is supported on the current device/browser. If not, the AR button is disabled or hidden.
  2. User taps "View in AR": The app might show a modal saying "Point your camera at an open area…", and then enters AR mode.
  3. Camera feed & model overlay: The device camera activates. The 3D model appears as if it's in the environment. The user can move closer or around it physically.
  4. User interaction in AR: The user can tap on a surface to relocate the model, or pinch on the screen to scale/rotate (these gestures are optional enhancements). The app keeps the model anchored where placed.
  5. Exit AR: The user taps an exit button or hits back. The app returns to the regular 3D view, with the model in its initial state.

Implementation checklist

  • AR support detection: Use if (navigator.xr) and navigator.xr.isSessionSupported('immersive-ar') to check for AR. Also ensure https: context. only enable AR button if true.
  • Request permissions: On button tap, call navigator.xr.requestSession('immersive-ar', { requiredFeatures: ['hit-test', 'dom-overlay'], domOverlay: { root: document.body } }). This triggers the camera permission prompt. Ensure you have an element (like a overlay div) for DOM overlay if you want to show UI on top in AR.
  • start AR session once the permission is given, use it with Three.js or PlayCanvas.
    • For Three.js: renderer.xr.setSession( session ); and then your render loop will adapt to AR. Use a HitTestSource for placing objects on surfaces (plane detection).
    • For PlayCanvas: call app.xr.start(camera, pc.XRTYPE_AR, pc.XRSPACE_LOCAL, { cameraComponent: yourCameraComponent }); which handles the session internally.
  • Place or scale model: Initially, you might just place the model at camera origin or at a default floor level. Using hit-test, you can update the model's position to the real-world hit point where the user tapped. Make sure the model's scale is reasonable (e.g., if your model units are meters, a small object might appear huge if units mismatched).
  • Visual feedback: While AR session is starting, show some indicator ("Initializing AR…"). Once the model appears, maybe show a brief help ("Tap on a flat surface to reposition"). This can go away after a few seconds.
  • Handle session end: Provide a button in DOM overlay to exit, which calls session.end(). Also handle if the user just hits Android's back or home – your app should listen for session.end event to know AR ended and then restore UI state.

Pseudocode


async function onEnterAR() {

if (!navigator.xr) { alert("AR not available"); return; }

const supported = await navigator.xr.isSessionSupported('immersive-ar');

if (!supported) { alert("AR not supported on this device."); return; }

// Request AR session

const session = await navigator.xr.requestSession('immersive-ar', {

requiredFeatures: ['hit-test', 'dom-overlay'],

domOverlay: { root: document.body }

});

// Set up AR rendering

app.viewer.startXRSession(session); // pseudo-call to integrate with viewer (Three.js or PC)

showMessage("Move your device to scan for surfaces");

// If using hit-test for placement:

const viewerRefSpace = await session.requestReferenceSpace('local');

const hitTestSource = await session.requestHitTestSource({ space: viewerRefSpace });

session.addEventListener('select', (evt) => {

// On screen tap in AR

const hit = /* perform hit test using hitTestSource */;

if (hit) {

model.position = hit.transform.position;

}

});

session.addEventListener('end', onARSessionEnd);

}

This is a simplification. In Three.js, much of this is abstracted when you use XRHitTest utility and set renderer.xr.enabled = true.

Troubleshooting

  • AR button not showing: Check the support detection. iPhones (Safari) will return false for immersive-ar support as of now, hence no AR. That's normal – document it to users ("AR works on Android or specific devices only").
  • Permission denied: If the user rejects giving you permission to the camera then you should gracefully fail. Maybe with retry functionality ("Enable camera in settings to use AR" message?). Don't silently fail.
  • Model not appearing in AR or too small in AR: Could be a scaling problem. Often in AR systems 1 unit is considered 1 meter. So if you have a model that was in arbitrary scale you might need to multiply or divide the scale when you enter AR. If for example you have a small object but it's showing up like microscopic multiply your scale by some factor to get it to the right size.
  • Model drifting or jittering: Probably a problem with AR tracking in low feature environment (say an empty wall). Try to encourage the user to move at slower pace or in a more textured environment. Also make sure you're using XRSPACE_LOCAL or LOCAL_FLOOR as the reference space to reduce the drifting as much as possible.
  • Exiting AR freezes camera feed: Occasionally, on some Android devices, after ending an AR session, the camera might get stuck if the session isn't properly ended. Make sure to call session.end() and also dispose of any AR-specific resources. If using Three.js, set renderer.xr.setSession(null) after end.
  • Performance in AR: AR mode might run a bit slower because the device is doing camera passthrough and tracking in addition to rendering the splats. If frame rate is low, consider reducing rendering load (you can dynamically lower point size or density during AR if needed). Also, ARCore might drop the camera frame rate on older devices.

By implementing AR, you significantly enhance the viewer's utility – seeing a photorealistic scene in context is a "wow" feature (imagine placing a scanned outdoor scene on your table or viewing a captured room in your own living room). Just be mindful of the caveats above for a smooth experience.


8) Testing Matrix

When you think you have everything working, it's time to test across scenarios. Using this matrix, make sure your Gaussian Splat PWA and integration is robust to different scenarios:

ScenarioExpected ResultNotes
Sample model on DesktopLoads and is navigable at good FPSBaseline environment (Chrome/PC). Also test in Firefox for basic viewing (no AR there).
Mock device (no camera)Viewer works (AR button hidden/disabled)E.g., using Chrome dev tools device emulation. Ensures graceful degradation when AR not available.
Real device – close rangeModel appears with high detail, low latencyTest on a powerful phone (e.g., Pixel 7 or iPhone 14). Should be smooth ~60fps in normal view. AR at least 30fps.
Real device – background/lockedApp resumes correctlyWhile viewing, switch apps or lock screen, then return. The viewer should still function or at least not crash. PWA might need a reload if suspended long.
Permission denied (AR)User sees clear error, app continuesManually deny camera permission on AR prompt. The app should handle it (e.g., show "AR unavailable without camera" toast and return to 3D view rather than a black screen).
No internet (offline)PWA opens (if cached), model maybe limitedIf user opens the app offline after first load, it should at least show the interface. If the model was cached (check caching strategy), it shows; if not, a friendly message "No internet – unable to load model" should appear.
Slow networkLoading indicator visible until doneThrottle network and ensure the user isn't staring at a blank screen. Your spinner or progress (if you have one) should show during model download. Possibly handle partial load if using progressive loading (antimatter15's viewer progressively loads points).
Different model sizesWorks for small and large modelsTry a simple model (~5MB .ply) and a heavy model (50MB+ .ply). The heavy one might take longer; ensure no timeouts. On very heavy, you might see memory issues on mobile – document a recommended point count or use compression (SOG).
Multiple navigationsNo memory leaks, no duplicated listenersIf your integration is in a single-page app, navigate away from and back to the 3D view multiple times. FPS should remain consistent and memory use stable. If it degrades, likely some Three.js scenes weren't disposed.
Unsupported browserUser gets a polite messageTest IE11 (just kidding, we simply wouldn't support that at all). But maybe test an older device with WebGL disabled, or Chrome with flags turned off. The app should detect lack of WebGL/WebXR and show an informative alert instead of failing silently.

use this table to record. As you find problems, update the app and retest the scenarios accordingly. It's a good idea to automate some of these (for instance, a Cypress or Playwright test that loads the page and checks for a WebGL context, etc., but manual testing is key for AR).


9) Observability and Logging

to maintain/improve your gaussian splat viewer app:

  • Model Load Events: Log start/end of model load. Log time taken. e.g. model_load_start model_load_success (with time taken) model_load_fail (with error info) This will help to detect any long loading times/failures for users
  • Rendering performance: If possible, log the frame rate or timing stats. For example, after 5 seconds of use, capture the average FPS or whether the device had to reduce quality. You might send an event like render_perf { fps: 55 } or simply log to console for devs.
  • User interactions: Log important actions enter_ar_start enter_ar_success enter_ar_fail (if AR session fails) exit_ar Also, if your app has multiple views or hotspots, log when user switches view view_changed_to: X
  • AR session stats stats about how long people spend in AR (e.g. log something on AR start and on AR end to calculate duration) also log if any tracking lost events happened (we don't get that directly in WebXR, but it may be a clue if people are leaving quickly)
  • Error logging: Any caught exceptions (loading errors, WebGL context lost, etc.) should be reported (to console for dev, or to a monitoring service in prod). For instance, if a user's device can't support the required texture size or runs out of memory, catch that and log error: "WebGL context lost due to OOM".
  • Device info: It's useful to tag logs with device or browser info (e.g., platform: iOS-Safari or Android-Chrome, plus device model if accessible). That way, if a particular phone model has issues, you can spot it.
  • Connection/reconnection (if applicable): If you had a concept of connecting to a hardware device (not really in this PWA case), you'd log connect_start, connect_success, etc. In our scenario, the "connection" is more about checking AR availability or retrieving model data, which we already covered above.

by observing these logs, (if you are incorporating with an analytics service then even better) you'd be able to understand things like "is people actually using the AR feature? Are many failing to load the model. what is the median time of loading on mobile or desktop etc" etc.. it's the feedback loop which will help you to take focus for improvements (eg: maybe you need to put more effort into compressing things if the load times are bad? or maybe you should simplify the flow for AR as many people are not doing that).


10) FAQ

  • Q. Is it necessary to have pro level camera equipments from the very beginning?

A. You can use even mobile phone camera for small scenes or objects. Any images will do. However, for large or critical projects, a decent camera with manual settings yields better results (sharp, consistent images). Even if you don't own a camera, you can still test out using some sample data we've provided. Really the most important thing is to have pictures of the subject from a lot of different angles with the same lighting conditions.

  • Q: What devices can I view on?

A: Any device that supports WebGL (in their browser) will be able to view your 3D model. Most modern smart phones, tablets and computers. As of now, AR mode is fully supported for Android devices with ARCore (and running Chrome/Edge browser). iPhones/iPads can view the 3D model in Safari but unfortunately due to Apple's current limitations web AR cannot be supported within the browser (as of early 2026). And if you have a high end VR headset that has a browser (Meta Quest with Oculus Browser, etc) you can go into VR mode and view your scene in immersive 3D! Keep in mind, you'll want to test on your target devices to see how things perform. (Depending on hardware)

  • Q: Can I use this in production, or is it a toy/preview?

A: Gaussian Splatting is relatively new, but it's maturing quickly. Some people are already using it in production (e-commerce demo, online exhibition, etc.). And there are solid, open-source tools like SuperSplat from PlayCanvas, or Spark. But it's an evolving technology, so file format could change (for example, more efficient SOG format could replace raw PLY in the future), and the browser technology (WebGPU, WebXR) is advancing. So you should be able to pilot it in production for web experience, especially if it's for marketing/visualization. But don't use it for mission critical stuff, before properly testing it. And be mindful of the data size and performance on your users device (provide compressed models if possible).

  • Q: Easy way to share/publish my 3d scene?

A: Fastest way: use SuperSplat Publish. In SuperSplat editor, you go to File Publish. Enter some information, and it will host your model on a URL for you. It even lets you mark it unlisted if you want to keep it semi-private. The page that goes out is basically a PWA viewer you can get anyone to load. If you want to host your own you can export an HTML from supersplat or use antimatter15 viewer html. So that you could have your own web page with the html+model. If you are looking for integration in an existing app you would need to do the steps in section 6 to embed it. Not just provide a link.

  • Q: Is there a way to edit/augment the splat model once created?

A: Not really, it's more like a photo. So if you wanted to add new things or remove from the scene you'd normally need to re-capture/regenerate the model or use the editing features in SuperSplat to isolate parts. There is some post-processing that can be done with SuperSplat Editor. Like cropping out background or combining multiple splats in a scene. But you can't, for example, dynamically insert a new 3D object into a baked splat scene and have it interact realistically with the splats (there are no dynamic shadows cast on splats, etc., currently). For adding annotations or hotspots, you can overlay those in the viewer (e.g., Reflct's approach of adding metadata and UI on top).

  • Q: The quality isn't as good as I expected. How can I improve it?

    A: A few tips:

    • Better input photos: The reconstruction quality depends on your photos. Use higher resolution images, cover the subject from more angles (including high/low angles, not just around the middle), and ensure focus/exposure are consistent. Fewer but well-planned shots are better than blasting hundreds of random shots. Avoid motion blur and dramatic lighting differences between shots.
    • Tune the reconstruction: If using an open-source pipeline, some allow adjusting the resolution or number of Gaussians. More points can capture detail better (at cost of file size). Also, filtering out outliers (noisy points) improves visual quality.
    • Viewer settings: In some viewers you can adjust point size or enable smoothing. For example, Spark might allow different shader modes that could make the splats blend nicer. PlayCanvas engine improvements in 2025 significantly boosted rendering quality and performance (smoother splats with fewer artifacts), so use the latest viewer tech available.
    • Post-process: If you have minor gaps or holes, you can mesh the splat point cloud and fill holes using mesh tools, but that may reduce photorealism. It's an active area of research to make these splat models even more high-fidelity; keep an eye on updates.
  • Q: How is this different from point clouds or photogrammetry?

    A: Gaussian Splats are like point clouds on steroids. Traditional photogrammetry often produces a mesh or dense point cloud; Gaussian Splatting instead optimizes point size, color, and opacity to represent the scene with fewer artifacts and with some volume (each point is a tiny 3D Gaussian blob). This results in smoother blending of points (less "holey" than raw point clouds) and surprisingly good preservation of photorealistic details. It's also generally faster to render than a heavy textured mesh. However, it's a complement to those techniques – in fact, many pipelines (like Luma or NerfStudio) can output both NeRF and point cloud models. Think of 3DGS as a modern approach to get NeRF-like visual quality with point cloud-like simplicity in rendering.


12) Changelog

  • 2026-01-10 — Verified with SuperSplat Editor v0.22.0 and Spark v1.0.0 on Chrome 117 (Windows 11, NVIDIA RTX 3060) and iPhone 15 (iOS 17 Safari). Added notes on AR support for iOS vs Android. Updated instructions to reflect PlayCanvas 3DGS improvements and SOG format introduction.
  • 2025-08-18 Initial version based on PlayCanvas blog announcements and Heliguy's workflow guide. Tested basic PWA installation and AR on Android Chrome. (Heliguy capture workflow reference)
  • 2025-05-22 Background: PlayCanvas released SuperSplat with PWA support around this date. This allows easier deployment. Ensured guide aligns with that capability (one click installation, PLY file association)
  • 2024-06-05 Background: PlayCanvas Editor integrated gaussian splats. Early experiments done with that editor. (multi-splat merging) informing the integration section. Noted need for user-friendly navigation (inspired by Reflct).
  • 2024-03-10 Background: Capture techniques research (Medium post by Y. He) gave advanced tips to enhance the quality. Those insights were distilled into the FAQ and capture guidelines.