SplatBridge — 3D Gaussian Splatting: Import, Stream & Play Real-World Scans
Bring photoreal scans of real places into Unity. Import SOG, SPZ and 3DGS PLY Gaussian Splatting captures, stream city-scale scenes under a fixed GPU budget, add collision and VR. Built-in/URP/HDRP.
by Stray Cats
Price History +
SplatBridge brings photorealistic scans of real places into Unity — scenes
captured with 3D Gaussian Splatting, a technique that turns ordinary photos
and drone footage into striking, explorable 3D. Drop a .sog, .spz or 3DGS .ply
file into your project and it renders in Built-in, URP or HDRP like any other
asset: walk through it, give it collision and gameplay, take it to VR. When a
capture is too big for GPU memory, SplatBridge streams it under a fixed memory
budget you set once — city-scale scans included.
📖 Full manual, troubleshooting table and tuning guide ship inside the
package, in English and Japanese. 🎬 Demo video in the gallery above. All gallery images are unedited in-Unity captures.
💬 Support: publisher contact on this page.
## Import: one step, three formats
**SOG** (PlayCanvas / SuperSplat), **SPZ** (Niantic, v3 gzip and v4 NGSP+zstd)
and **3DGS PLY** (SH degree 0–3). Drop a bundled .sog, .spz or .ply into your
project for a render-ready GaussianSplatAsset — no external converter, no
command line. An unbundled SOG (meta.json plus its WebP files) imports through
an editor menu instead, in the same one step. superspl.at datasets import as
they are; to build a streamed SOG from your own .ply, use PlayCanvas's free
splat-transform CLI (one command, in the README), then bake it in the editor.
## Rendering: every pipeline, correct compositing
- **Every render pipeline.** Built-in, URP (Unity 6 Render Graph, with
Compatibility Mode fallback) and HDRP (Custom Pass). Shaders ship inside the
package and are included in player builds automatically — no "Always
Included Shaders" setup.
- **GPU depth sorting.** A radix sort in compute re-sorts the draw order as
the camera moves, never on the main thread, with an automatic background
CPU fallback where compute sorting is unavailable (specifics under
Technical details).
- **Render scale.** Draw splats into a downscaled offscreen target and
composite: fill cost drops roughly with scale², UI and geometry stay full
resolution. XR has a stereo-array version of the same lever.
- **Correct compositing.** Splats depth-test against your scene, so scanned
content sits behind walls and props instead of floating over them.
## Streaming: city-scale under a fixed budget
Large captures do not fit in GPU memory, so SplatBridge streams them under a
**hard resident-splat budget** you set once.
- **No per-dataset tuning.** Quality is judged in screen space, not by
distance: the one quality knob, **Splat Quality Pixels (τ)**, means the
same thing on a tabletop scan and on a city. It ships at a fixed **2 px on
every platform**, so one scene ships to desktop, PCVR and Quest alike; an
optional **Auto** preset resolves it per platform instead, letting mobile
trade detail for fill automatically.
- **Coarser, never holes.** The plan pays for every cell of the dataset before
spending anything on detail, so an under-sized budget is absorbed by drawing
the scene **coarser**, not by dropping parts of it.
- **Know before you ship.** The bake log and the inspector report a **coverage
gate** verdict up front: a budget too small even for the cheapest complete
view is caught in the editor, not discovered on device. An optional debug
log prints coverage, achieved quality, the error distribution and the
frame-time knee, so tuning is measurement rather than guesswork.
- **Fixed memory.** Max Resident Splats is a hard memory cap and the main
performance lever — τ sets quality. The GPU buffer is allocated once at
that size, with per-frame upload budgets, frustum culling and no-flash
chunk swaps.
- **Pre-baked, so the runtime never decodes.** A one-click bake (.splatbake)
turns a streamed-SOG dataset into GPU-ready records, so a runtime chunk load
is a seek and a read with no image decoding in the loop.
- **Live in the editor.** The Scene view runs the real streaming loop before
Play — same worker, same budget, same LOD cuts — and idles once converged;
move the camera to resume.
## Make it a game
A scan you can only look at is a screenshot. SplatBridge ships the parts that
turn one into a scene:
- **Collision.** One context-menu entry builds a MeshCollider from the splats
(opacity-weighted voxel occupancy with a weight threshold that filters out
lone floater noise). Because it is ordinary static collision geometry, **CharacterController,
Rigidbody, raycasts and NavMesh baking all just work** with stock Unity
physics. Also available from code at runtime. Collision covers the whole
dataset regardless of what is currently streamed in.
- **Reveal / hide animation.** Five patterns (Scatter, FromPoint, Rain,
Dissolve, Sweep) animate the **actual gaussians** in the vertex shader — no
particle-to-splat handoff pop, and the fully revealed frame is exactly the
normal render. It can wait for the streamer's first full coverage, so the
scene converges at once instead of popping in.
- **VFX Graph bridge.** Sample the live splat buffers from VFX Graph: particles
that spawn on the scanned surface, inherit its color and sync to the reveal
wave. Two ready-to-paste HLSL recipes are in the manual.
- **Runtime loading.** SplatRuntimeLoader.LoadFromFile(path) loads .sog / .spz /
.ply at runtime; errors surface as typed exceptions with the cause
(unrecognized container, unsupported version, corrupt data …), not silent
failure.
- **Helpers.** A streaming/FPS debug HUD you can ship in builds, and a
burned-in credit overlay for CC-BY scans.
## VR — and experimental Meta Quest standalone
**PC VR (URP) is a first-class target:** Single Pass Instanced and Multiview
stereo, verified on Quest 3 over Link (OpenXR). The sort follows the head
pose, so depth ordering holds up as you look around.
SplatBridge also runs on Quest 3 standalone (Android, OpenXR, Vulkan, Multiview) —
the same importer, streamer, GPU depth sort and stereo path as on desktop,
with one-time StreamingAssets extraction handled for you. It works on device
today.
Standalone is labelled **experimental** on purpose. Performance on standalone hardware
depends heavily on the size of your capture and on your settings, and tuning
work is ongoing. Treat it as something to prototype and measure with, not as a
platform where a given frame rate is guaranteed.
Standalone rendering is **fill-rate bound** rather than CPU or sort bound, and
the package gives you the levers that move it. The streaming rules above still
hold: a lower budget renders coarser, and the coverage gate warns before you
build.
One more lever where fill binds: an experimental, opt-in **impostor** bakes the
far field into a billboard, so the live draw only pays for near splats. The
included Quest scene ships it on and tuned.
A starting point on Quest 3 (then measure in your own scene):
- Max Resident Splats: **1,000,000** — drop to 500,000 if your title's frame
time is tight
- Splat Quality Pixels (τ): **2 (the shipped default — leave it)**. In our
Quest 3 testing the fixed 2 px held up; raise τ toward 8 (or select the Auto
preset, which resolves to 8 px on Android/Quest) only if a heavy scene turns
fill-bound
- XR Splat Render Scale: **0.6**
- Quad Extent Sigma: **1.4** (default 3) — much less fill; the size-aware sigma
boost (on by default) keeps large on-screen splats round, not square-cropped
- Sort Mode: **Auto** (GPU sort on Vulkan)
None of that is per-dataset: τ is scale-free, so the same numbers carry over to
your next capture.
The package README documents the Android build setup (IL2CPP / ARM64 /
Vulkan, OpenXR with the Meta Quest feature group, Multiview, and URP renderer
feature setup), and the **tuning panel sample** below sweeps these knobs
in-headset.
## Included samples: 3 ready-made scenes
Press Play once and everything runs.
- **Demo scene.** An indoor classroom (1.9M splats, 86 MB) with a ready-to-play
scene: streaming, a Sweep reveal, a camera dolly and physics balls rolling on
a collider generated from the splats.
- **Tuning panel.** An in-headset panel that shows the streaming and frame-time
telemetry and lets you sweep the tuning knobs (budget, τ, render scale, quad
extent) with the controller while wearing the device. Comes as a ready-made
scene (XR rig, streamer and panel already wired): open it, build, and sweep.
- **Quest scene.** A ready-made standalone-headset scene (XR rig, floor and
streamer already wired) whose streamer carries the Quest configuration out of
the box, so the first build you send to the device starts from settings that
are known to run. Its README lists the Android/OpenXR project settings a scene
cannot carry itself. Both XR scenes stream the classroom set.
Every bundled dataset is our own content — nothing to credit.
## Requirements
- Unity 6000.x (tested on 6000.0–6000.5).
- Built-in, URP 17.x or HDRP 17.x.
- Windows / macOS desktop and Android (including experimental Meta Quest 3
standalone — see above). WebGL is not supported (streaming needs file IO and
compute).
- VR/XR is URP only (OpenXR). Built-in RP and HDRP XR are not supported.
## Known limitations
- Meta Quest 3 standalone support is **experimental** (see above): budget time
to tune with the included panel, and treat it as experimental in your own
planning.
- Color uses the SH DC term only. SH bands 1–3 are imported and stored, but not
yet used by the shader (view-dependent color is on the roadmap).
- Streaming reads local files (no HTTP streaming yet) and requires the baked
format; the importer produces it in one step.
- Splat editing (delete / select / crop) is out of scope — use SuperSplat and
re-export.
## Roadmap (no dates promised, order may change)
- Standalone Quest performance — continued optimization of the mobile GPU
path, aiming to drop the experimental label
- iOS (iPhone / iPad)
- SH bands 1–3 in the shader
- HTTP streaming of remote datasets
All 1.x updates are free for purchasers.