STATION 00 — ENTRY

CaveViewer logo

See the whole cave
before you swim it.

CaveViewer is a free 3D viewer built for cave divers and survey teams, made to open photogrammetry scans too large for anything else — models far bigger than your computer's memory — and fly through them smoothly on Windows, macOS, and Linux.

Free. No ads. No account. Works offline once installed. Windows, macOS & Linux.

CaveViewer rendering a textured cave passage in photogrammetry detail, with the minimap and bottom-right control column visible

Inside an actual cave scan, fully textured — minimap bottom-left, and the full control column bottom-right: brightness, global light, distance, then mesh / texture / shade / open / help / color / rec.

Station 01
The Tool

Built for scans too big to open anywhere else

A multi-gigabyte cave scan will choke most viewers. CaveViewer splits the model into a 3D grid of spatial chunks and only keeps the chunks near your current position loaded — so frame rate stays smooth no matter how large the full system is.

Navigation

Fly through it like you're really there

Free-fly camera with no gravity or floor — WASD to move and strafe, E and Q for up and down, and hold left-click while moving the mouse to look around (or use J/L/I/K on the keyboard). Z/X barrel-roll the view, and Shift is a speed boost. Camera bookmarks let you return to a spot instantly — save with Ctrl+1–9, jump back with 1–9, clear one with Del+1–9.

Lighting

Headlamp, plus an ambient fill when you need it

Adjustable headlamp brightness for the cone in front of you, and a separate global light that raises a flat ambient fill across the whole cave when you want to see everything at once.

Orientation

A minimap that knows where the passage actually is

Click anywhere on the minimap to jump there instantly — it lands you inside the actual passage near your current depth, not floating in empty rock. Ctrl+0 levels your view back to the horizon without moving you.

Inspection

Mesh, texture, or flat-faceted shading

Toggle wireframe to inspect scan density and quality, toggle the photo texture on or off, and switch between smooth and flat-faceted shading to read the raw triangulation of the scan.

CaveViewer showing a dense cave mesh in pure wireframe mode, Mesh on and Texture off

Recording

Record a clean flythrough to MP4

Press REC to arm a 3-2-1 countdown; the interface clears and CaveViewer records your flight straight to an MP4 file — no in-memory buffer. Stop or cancel any time with Shift+R. Full breakdown below.

Multiple maps

Switch caves without closing the program

Open a different map mid-session with one click, or Ctrl+O. First-time imports show real progress in-window; maps you've opened before load instantly from a local cache.

Always current

Download updates from the launch screen

CaveViewer checks a signed update manifest on launch. Start a download and keep working — it continues in the background. After verifying the package, CaveViewer keeps it in your Downloads folder and reveals it for you to install manually. It never runs or installs anything for you.

Any machine

Windows, macOS, and Linux, the same way

Download the build for your system and run it. The controls and features are identical everywhere.

No size limit

Built for scans way past what fits in memory

Very large exports are read in a single streaming pass and written straight to disk in spatial pieces, so opening a scan never requires loading the whole thing into RAM at once — even when the file is far bigger than your computer's memory. The first time a map opens, this one-time import shows its progress on screen:

Import progress ring: Scanning map
Scanning map
Import progress ring: Parsing geometry
Parsing geometry
Import progress ring: Finalizing map cache
Finalizing map cache
Import progress ring: Opening cave
Opening cave

Tuning

Preferences for underpowered laptops and huge caves

An optional Preferences panel lets you cap how much RAM and GPU memory CaveViewer uses, how many background threads load and import chunks, and how big those chunks are — useful on a laptop, or when importing a scan on the larger end. Full breakdown below.

CaveViewer's Preferences window, Streaming tab, showing memory and worker fields

Customization

Set the void to whatever color helps you see

The empty space beyond the scan doesn't have to be black — drag the R, G, and B sliders in the Color panel to pick a background that makes wireframe or thin passages easier to read against.

CaveViewer's Background Color panel open, with R, G, and B sliders

Station 02
Compatibility

Bring your own scan

CaveViewer reads the formats survey and photogrammetry software actually export. Point it at a folder, and it works out the rest.

.OBJ + .MTL + tiled .JPG — Agisoft Metashape and similar photogrammetry exports
.GLB — binary glTF, including models with textures embedded directly in the file

Station 03
On Screen

Every control in one column, one corner

Every adjustable control — headlamp brightness, global light, render distance, the mesh/texture/shade toggles, the color picker, opening another map, and recording — lives in a single column anchored to the bottom-right corner, and applies live while you're still flying.

BRIGHTNESS − 5 +    GLOBAL LIGHT − 5 +    DISTANCE − 3 +
[ MESH ] [ TEXTURE ] [ SHADE ]   [ OPEN ] [ HELP ] [ COLOR ] [ REC ]
Close-up of CaveViewer's bottom-right control column: Brightness, Global Light, Distance, then Mesh, Texture, Shade, Open, Help, Color, and Rec buttons

The whole column, live — the three steppers up top, then Mesh / Texture / Shade, then Open / Help / Color / Rec.

CaveViewer's full-screen controls reference, grouped into Move, Look, Navigate, and Record

This full reference appears automatically while a map loads, and any time after via the HELP button — grouped into Move, Look, Navigate, and Record, including the camera bookmark slots.

Station 04
On The Record

Record a clean flight to share

CaveViewer can capture your flythrough as a video, straight to disk while you fly — nothing is held in memory, so even a long recording won't balloon your RAM.

Press REC to start a short 3-2-1 countdown. The minimap, controls, and control column disappear so nothing clutters the shot, then recording begins. Press Shift+R to cancel the countdown or to stop a recording in progress.

Files are saved as MP4 to ~/Movies/CaveViewer/ (you can change this folder under Preferences → Storage), scaled to 720p by default to reduce recording load. Set CAVEVIEWER_RECORDING_MAX_HEIGHT=1080 to opt back into 1080p. Each file is named for the date and time it was captured, e.g. CaveViewerDive-20260715-162609.mp4.

CaveViewer with the interface cleared and an amber ring counting down before recording begins

REC armed — the interface clears and an amber ring counts down before capture starts.

CaveViewer showing the Recording saved confirmation with the output MP4 file path

When you stop, CaveViewer confirms the save and shows exactly where the MP4 landed.

Station 05
Getting In

Install

Grab the build for your system — no Python install, no terminal commands to memorize, no dependencies to hunt down.

  1. Download the build for your platform

    From the Releases page, grab the .dmg for macOS (Apple Silicon or Intel), the .zip for Windows, or the Linux x86_64 .AppImage.

  2. Install it

    macOS: open the DMG and drag CaveViewer into Applications. The first time it opens, go to Settings → Privacy & Security and allow it to run.
    Windows: extract the zip and double-click launch.bat. It installs Python if needed, the Visual C++ runtime and required libraries, opens a firewall rule so update checks can reach GitHub, and creates a Desktop shortcut.
    Linux: run chmod +x CaveViewer-*.AppImage, then launch it directly — no system install needed.

    CaveViewer Setup window, ready to install, listing the setup steps

    Ready to install

    CaveViewer Setup window mid-install, with a live log

    Installing, live log

    CaveViewer Setup window showing the CaveViewer is ready dialog with all steps checked off

    Ready to launch

    The CaveViewer desktop shortcut icon

    On your desktop

  3. Launch CaveViewer

    You'll land on the splash screen. Click Open Map Folder… — or use the Map Library if you don't have a scan of your own yet and want to try it first.

  4. Point it at your map

    Choose the folder with your .obj (+ .mtl + textures) or .glb file. The first time you open a new map it imports and caches it once — every open after that is instant.

CaveViewer's splash screen with the logo, version number, Open Map Folder button, Preferences link, and Map Library panel

What you see on launch — click Open Map Folder… or try a standard library map.

CaveViewer's progress screen while importing a brand-new map for the first time

First time opening a new map only — every open after this is instant.

CaveViewer's Map Library dialog, listing Devils Eye and Peacock Springs Cave System

No scan of your own yet? Download a real cave system — Devils Eye or Peacock Springs — from the Map Library and open it the same way.

Station 06
Tuning

Preferences, explained

Most people never need to open this. It's here for large maps on constrained hardware, or for squeezing more out of a strong machine. Open it from the splash screen with Preferences. Streaming settings apply live to your current session; Import settings only affect a map the next time it's imported or re-imported; Storage sets where recordings are saved.

Streaming

Applies immediately, every launch

System RAM target (%)default 8

Share of total system RAM that loaded chunks are allowed to use. Higher keeps more resident at once, at the cost of leaving less RAM for everything else.

GPU memory target (%)default 70

Share of the detected GPU memory budget used for loaded chunks. Push it too high on a weaker card and you risk stutter instead of smoothness.

GPU memory override (GB)default empty

Optional manual GPU memory ceiling. Only needed if auto-detection gets your GPU's size wrong; a smaller detected GPU still wins.

Loading worker limitdefault 2

Cap on background chunk-loading threads. The actual count can drop lower when CPU or RAM is constrained.

Loading CPUs to keep freedefault 3

Logical CPUs held back from the loading pool, so streaming doesn't take over the whole machine.

Chunk uploads per framedefault 1

Hard cap on how many ready chunks are uploaded to the GPU each frame. A higher cap brings new chunks on screen faster when flying fast, at the cost of occasional frame-time spikes.

Upload groups per framedefault 1

Hard cap on material groups uploaded from one ready chunk each frame. This spreads huge chunks across multiple frames instead of uploading all VBOs and textures at once.

Upload budget (ms)default 3.0

Soft per-frame time budget for chunk uploads. A larger budget uploads more before yielding — smoother streaming, but a slightly heavier hit each frame it happens.

Import

Only affects the next import / re-import

Import chunk size (m)default 50

Spatial chunk size used when building new cache data. Smaller chunks give finer streaming control in tight, twisty passages; larger chunks mean fewer draw calls in big open rooms.

OBJ scan throttle (ms)default 0 (1 on Windows)

A small yield during OBJ scanning keeps the machine responsive on slower disks, at the cost of a slightly longer import.

Cache-building worker limitdefault 1

Cap on chunk-cache writer threads for the one-time import. The actual count can drop lower when CPU or RAM is constrained.

Cache-build CPUs to keep freedefault 2

Logical CPUs reserved during import so the rest of your system stays usable while a huge map is being chunked.

Storage

Where files are saved

Recordings folderdefault ~/Movies/CaveViewer

Where saved MP4 flight recordings are stored. Point it anywhere writable, or a folder that can be created.

Downloaded maps folderdefault ~/Downloads

Where CaveViewer stores downloaded Map Library maps. Point it anywhere writable, or a folder that can be created.

CaveViewer Preferences window, Streaming tab

Streaming — runtime memory, worker, and upload behavior.

CaveViewer Preferences window, Import tab

Import — chunk size and cache-build behavior.

CaveViewer Preferences window, Storage tab, showing the recordings folder

Opened from the splash screen's Preferences link. Saved on Linux under ~/.config/caveviewer/; on macOS and Windows under ~/.caveviewer/.

Station 07
Field Notes

The dives behind the data

The scans CaveViewer opens come from real mapping expeditions. Here's footage from two of the systems the tool has been tested and used on.

Video thumbnail: Wes Skiles Peacock Springs State Park 3D Mapping Initiative Watch on YouTube

Wes Skiles Peacock Springs State Park — 3D Mapping Initiative

Peacock Springs, near Live Oak, Florida, is one of the longest underwater cave systems in the continental U.S. — nearly 33,000 feet of surveyed passage across two major springs and six sinkholes. This covers the effort to map it in 3D.

Video thumbnail: Devil's Eye Mapping Update, February 2026 Watch on YouTube

Devil's Eye — Mapping Update, February 2026

Devil's Eye is one of the entrances into the Ginnie Springs cave system in High Springs, Florida, and one of the most-dived training cave systems in the world. This is a progress update from the ongoing effort to map it.

Station 08
Surface

Built by people who use it

CaveViewer started as a way to actually look at the survey data from real dives, not just collect it.

Brian Deatherage (K3rnalPanic)
CO-CREATOR · BOTTOMLINE PROJECTS SCIENTIFIC DIVE TEAM
Zsolt Szabo
CO-CREATOR · BOTTOMLINE PROJECTS SCIENTIFIC DIVE TEAM
magic mr_v
CONTRIBUTOR