The first ROS 2 plugin that loads or streams trained 3D Gaussian Splats and renders them live next to your TFs, markers and point clouds.
.ply, rendered into RViz 2 alongside the standard tooling.
3D Gaussian Splatting has become the leading photorealistic scene representation — used in dense visual SLAM (Gaussian-SLAM, MonoGS, SplaTAM), in sim-to-real environment capture, and as a backdrop for teleoperation. But every GS viewer out there (the Inria reference, splatviz, antimatter15's WebGL splat) is a standalone tool, disconnected from a robot's TF tree, sensor data and markers.
That's the gap RVizSplat fills. Trained splats reach RViz 2 either as
a .ply or as a splat_msgs/SplatArray on a ROS topic, then render
with custom Ogre-side shaders at interactive framerates alongside TFs, markers and the
rest of the scene. Every knob is exposed as a real RViz Property.
Load a .ply file once, or subscribe to a
splat_msgs/SplatArray topic for live updates. Switch at runtime.
Exact back-to-front Sorted blending (default), or four-pass Weighted Blended OIT — toggleable per scene from the property tree.
CPU pdqsort on a worker thread, or CUDA radix sort. Hot-swappable; the render thread never blocks on either.
Splats live in render queue 95, opaque RViz primitives at queue 94. The compositor catches them automatically.
Axis-aligned crop to trim floaters, hide ceilings, isolate a workspace — without
touching the source .ply.
Sliding-window FPS, per-stage timings (cpu_sort, cuda_sort,
render), TBO byte stats. Logs survive in robot logs.
A typed message and two source loaders feed an Ogre MovableObject that owns a
packed GPU layout, a worker-thread sorter and an EWA + spherical-harmonics shader. From
there the splats take one of two parallel transparency paths.
Sorted mode runs the depth sort on a worker thread (CPU
pdqsort or CUDA CUB radix behind one ISplatSorter interface), reads the result
from a lock-free pickup, and the GPU draws back-to-front with standard pre-multiplied alpha.
Exact, predictable, fastest on small scenes.
WBOIT mode skips the per-frame sort entirely. A four-pass Ogre compositor (opaque scene, weighted accumulation, transmittance product, full-screen resolve) approximates correct transparency in one render pass. It coexists with native RViz primitives without a global sort, and is the right default when the CPU is contended.
We compare RVizSplat against the two most-used standalone GS viewers using the canonical novel-view metrics — PSNR, SSIM, LPIPS — on identical viewport coordinates per scene.
| Renderer | PSNR ↑ | SSIM ↑ | LPIPS ↓ |
|---|---|---|---|
| splatviz | 23.025 | 0.823 | 0.126 |
| antimatter15/splat (WebGL) | 21.985 | 0.765 | 0.163 |
| RVizSplat | 22.568 | 0.771 | 0.148 |
We hold the global viewport pose fixed across all three viewers, render each scene, and
compute PSNR / SSIM / LPIPS against the held-out reference views. The full evaluation
script is in the repo at evaluation/eval.py — image quality reports are
first-class output.
| Sort backend | Lives inside RViz 2 | ROS integration | |
|---|---|---|---|
| splatviz | GPU only | — | — |
| antimatter15/splat (WebGL) | CPU only | — | — |
| RVizSplat | CPU + CUDA | Yes | Yes (splat_msgs) |
Which sort backend and transparency mode to pick depends on your GPU, scene size, and how much CPU you can spare for rendering.
| Hardware | Scene size | Recommendation | Why |
|---|---|---|---|
| Discrete GPU | Large > 7–8M splats |
Sorted + CUDA radix | Beyond roughly 7–8M splats CPU pdqsort starts to lag; the GPU radix sort takes over and eliminates the bottleneck. |
| Discrete GPU | Small / medium ≲ 6M splats |
Sorted + CPU pdqsort | pdqsort holds up well into several-million-splat territory in our tests; CUDA setup overhead isn't worth it at this scale. |
| Discrete GPU | any (CPU contended) | WBOIT | When other robot modules are competing for cores, skip the sort entirely. |
| Integrated GPU | Small / medium | Sorted + CPU pdqsort | CPU sort holds up at this scale; visual fidelity stays exact. |
| Integrated GPU | Large or CPU-contended | WBOIT | CPU sort becomes the bottleneck on integrated systems; WBOIT trades a small fidelity hit for steady framerate. |
| CPU only | Small | Sorted + CPU pdqsort | Medium and large scenes are unusable without a GPU; keep splats under ~500k. |
git clone --recurse-submodules https://github.com/RVizSplat/RVizSplat
cd RVizSplat
colcon build --symlink-install
source install/setup.bash
The fastest path. No publisher node needed.
rviz2
# Add → Gaussian Splats
# Source: PLY File
# Splat File: /path/to/scene.ply
For live splat updates from another node, or when the scene gets republished.
ros2 run splat_publisher ply_splat_publisher \
--ros-args -p ply_path:=/path/to/scene.ply
rviz2
# Add → Gaussian Splats
# Source: ROS Topic
# Topic: /gaussian_splats
Requires ROS 2 Rolling. Optional CUDA Toolkit for the CUDA radix-sort path — the plugin falls back to CPU pdqsort if CUDA isn't present.