Gaussian splats viewer that works in your terminal. Yes, it’s made of symbols!

A CPU-first 3D Gaussian Splatting viewer inspired by ratatui, built on crossterm. Fully parallelized rendering pipeline via rayon, perceptual color mapping, six render modes — all running on pure CPU. Real scenes with 1.1M splats hold 10–25 FPS. No GPU required. Works on potato.
Gaussian Splats are cool. Beautiful tech. Especially now with the rise of image-to-splat pipelines like SHARP. Btw, it will be soon available here.
Inspiration by ratatui merged with binge watching of Common Side Effects which resulted in building this “The Tortuise” TUI 3GS viewer.
| Feature | Details |
|---|---|
| 6 render modes | Halfblock (default), point cloud, matrix, block density, braille, ASCII. Cycle with M |
| Full 3D navigation | WASD movement, R/F vertical, arrow keys for yaw/pitch. Smooth held-key input |
| Two camera modes | Free (fly anywhere) and Orbit (auto-rotate around origin). Switch with Space |
| .ply and .splat files | Standard 3DGS formats. Binary little-endian PLY with SH coefficients, 32-byte .splat records |
| Built-in scenes | Bundled bonsai.splat (1.1M splats) and luigi.ply (14K). --demo runs a built-in demo scene |
| Terminal detection | Truecolor for modern terminals, perceptual 256-color fallback for Terminal.app. Zero config |
| Supersampling | 1x/2x/3x factor for higher fidelity at the cost of compute |
| Cross-platform | macOS and Linux |
Requires Rust 1.80+ (rustup update to upgrade)
# Install from crates.io (recommended)
cargo install tortuise
# Or build from source
git clone https://github.com/buildoak/tortuise.git
cd tortuise
cargo install --path .
# Built-in demo (no scene file needed)
tortuise --demo
# Load a bundled scene
tortuise --flip-y scenes/bonsai.splat
# Load any .ply or .splat file
tortuise your-scene.splat
tortuise your-scene.ply
# Some scenes need axis flips depending on capture coordinate system
tortuise --flip-y scene.ply
tortuise --flip-z scene.splat
tortuise [OPTIONS] [INPUT]
Arguments:
[INPUT] Path to a .ply or .splat scene file (use --demo for built-in scene)
Options:
--demo Run built-in demo scene
--flip-y Flip Y axis (some capture tools use Y-down)
--flip-z Flip Z axis
--supersample <N> Supersampling factor [default: 1]
--cpu Force CPU rendering
-h, --help Print help
-V, --version Print version
| Key | Action |
|---|---|
W / A / S / D |
Move forward / left / back / right |
R / F |
Move up / down |
| Arrow keys | Yaw and pitch (look around) |
Space |
Switch to Orbit mode |
M |
Cycle render mode |
+ / - |
Adjust movement speed |
Tab |
Toggle HUD |
Z |
Reset camera |
Q / Esc |
Quit |
| Key | Action |
|---|---|
| Arrow Up / Down | Adjust elevation |
| Arrow Left / Right | Nudge orbit angle |
Space |
Switch to Free mode |
+ / - |
Adjust orbit speed |
Truecolor (best experience): Ghostty, iTerm2, Kitty, WezTerm, Alacritty
256-color fallback: Apple Terminal.app – works, but reduced color fidelity. The perceptual color mapping does its best.
Auto-detected via COLORTERM, TERM_PROGRAM, and TERM environment variables. No configuration needed.
| Device | CPU | Scene | Reference FPS |
|---|---|---|---|
| Mac Mini M4 | Apple M4 | luigi.ply (14K) | 120+ |
| Mac Mini M4 | Apple M4 | bonsai.splat (1.1M) | 80+ |
| MacBook Air M2 | Apple M2 | luigi.ply (14K) | ✓ |
| MacBook Air M2 | Apple M2 | bonsai.splat (1.1M) | 20–30 |
| Jetson Orin Nano* | ARM Cortex-A78AE | luigi.ply (14K) | ~30 |
| Jetson Orin Nano* | ARM Cortex-A78AE | bonsai.splat (1.1M) | 10–15 |
Numbers in parentheses are splat counts. FPS is approximate and depends heavily on terminal window size — a smaller window (⌘-) renders fewer cells and runs faster. *Jetson tested over SSH, which may be a bottleneck.
The fastest way to get a real scene into tortuise is to grab one from SuperSplat – thousands of community-uploaded Gaussian splat scenes. The included scripts/supersplat-dl.sh downloads and converts any SuperSplat scene to a standard PLY in one command:
# Download a SuperSplat scene (paste any share URL or scene ID)
./scripts/supersplat-dl.sh "https://superspl.at/s?id=cf6ac78e" bee.ply
# View it
tortuise bee.ply
Requires Node.js 16+ and curl (for npx @playcanvas/splat-transform under the hood).
Other sources:
tortuise --demo – instant built-in demo scene, no downloads requiredBoth formats are well-supported: PLY files with spherical harmonic coefficients (f_dc_0/1/2) or direct RGB, and the compact 32-byte .splat format used by most web viewers.
The pipeline is straightforward: load splats, project them into screen space, depth-sort, splat onto a framebuffer, then convert to terminal characters. Each frame:
▄ character with separate foreground/background colors. Other modes use braille patterns, ASCII density ramps, or single characters.The frame target is 8ms (~120fps). On truecolor terminals, colors are passed as 24-bit RGB. On 256-color terminals, a perceptual distance function maps each pixel to the closest ANSI color – weighted toward green sensitivity, which is where human vision is sharpest.
Things I want to improve next – and contribution opportunities:
ratatui + tortoise = tortuise.
MIT – Nick Oak, 2026