A Tkinter + OpenGL desktop app for training and viewing 3D Gaussian splats from casual captures. NullSplats wraps COLMAP for camera poses, uses PyTorch + gsplat (plus optional monocular backends) for training/inference, and stores everything in a reproducible cache tree so you can resume scenes without redoing work.
Demo: https://github.com/user-attachments/assets/6bcda99b-5d9d-4960-a759-5008b4bdc766
.ply or .splat.cache/ for repeatable, resumable workflows.NullSplats supports three ways to create splats:
Gsplat 50-view: https://github.com/user-attachments/assets/0a5431de-d146-4192-8305-6ec645161ba1
Gsplat closeup: https://github.com/user-attachments/assets/01245b1e-0098-4ebb-ad6c-00e220ba4e85
DA3 5-view: https://github.com/user-attachments/assets/c5cf7697-eb91-4ee9-9f46-6190622df765
DA3 closeup: https://github.com/user-attachments/assets/b87fa2f9-23c9-4a3b-bba7-82734a069edf
SHARP 1-view: https://github.com/user-attachments/assets/127c5651-a7da-471f-8c65-5c65db2283b2
SHARP closeup: https://github.com/user-attachments/assets/c5599843-46d5-4d2f-ab3d-5881534f3c3e
Side-by-side comparison: https://github.com/user-attachments/assets/00e8449d-0f26-4258-8469-4dc7424652ca
Notes: SHARP’s single-view result is especially impressive. DA3 often nails geometry but can look “weird” or overly transparent; if that improves, it could be a standout few-view option.
Want to discuss development or get support? Open an Issue or join the Discord: https://discord.gg/nP8BMtZ42C
main.py - app entrypoint (Tk root + tabs)nullsplats/
ui/ - Tk UI, tabs, OpenGL viewers, shaders (ui/shaders/*.vert|*.frag)backend/ - frame extraction, COLMAP pipeline, splat trainingutil/ - logging, config, threading helpers and tool path defaultsbuild.bat - portable bundle builderrun.bat - launcher used inside the portable bundlerequirements.txt - Python dependenciesThe app centers around a small core state object (AppState), four UI tabs (Inputs, COLMAP, Training, Exports), and a backend pipeline that handles frame extraction, COLMAP structure-from-motion, and training/inference.
main.py sets up logging, creates AppState, and builds the Tk root in ui/root.py.ui/root.py wires the four tabs and routes scene selection between them.nullsplats/app_state.py owns AppState (config + SceneManager + current scene)nullsplats/backend/io_cache.py defines ScenePaths and metadata read/writeCache layout (per scene):
cache/inputs/<scene_id>/source (original source copy)cache/inputs/<scene_id>/frames_allcache/inputs/<scene_id>/frames_selectedcache/inputs/<scene_id>/metadata.jsoncache/outputs/<scene_id>/sfmcache/outputs/<scene_id>/splatscache/outputs/<scene_id>/rendersnullsplats/backend/scene_manager.py handles scene discovery, selection persistence, and thumbnail caching (thumbnails.db).
ui/root.py builds the ttk.Notebook, instantiates tabs, and coordinates tab changesui/tab_inputs.py + mixinsui/tab_colmap.pyui/tab_training.py + layout/preview mixinsui/tab_exports.pyWizard flows:
ui/tab_inputs_wizard.py (single popup with inputs + training preset + COLMAP options)ui/wizard.pyui/tab_inputs.pyui/tab_inputs_scenes.pyui/tab_inputs_grid.pybackend/video_frames.py, backend/scene_manager.pyui/tab_colmap.py runs SfM and manages COLMAP settings/logsbackend/sfm_pipeline.py (COLMAP CLI)ui/tab_training.py orchestrates training runs, manages logging, and owns preview stateui/tab_training_layout.pyui/tab_training_preview.pybackend/splat_train.py (gsplat training loop)backend/splat_backends/depth_anything3_trainer.py (Depth Anything 3 inference + gs_ply export)ui/tab_exports.py lists checkpoints, opens a preview viewer, and renders turntablesGLCanvas to display .ply checkpoints and imageio for video outputui/gl_canvas.py is the main preview surface
GaussianSplatViewer for live OpenGL displaySplatRenderer (gsplat rasterization) for offline renders and turntablesPreviewPayloadui/gaussian_splat_viewer.py is the OpenGL renderer (instanced quads + shaders)ui/gaussian_splat_camera.py contains camera math helpersui/shaders/gaussian_splat.vert and ui/shaders/gaussian_splat.fragui/render_controls.py (basic controls)ui/advanced_render_controls.py (debug/scale/camera)ui/colmap_camera_panel.py (apply COLMAP poses)util/threading.py runs background tasks and marshals callbacks to the Tk threadutil/logging.py sets a consistent console + file logger under logs/app.logutil/tooling_paths.py resolves default COLMAP and CUDA pathsffmpeg/ffprobe on PATH (video extraction)tools/colmap or user-provided pathtools/depth-anything-3)tools/sharp)Prereqs:
tools/colmap (or set in the UI)ffmpeg/ffprobe on PATHFrom repo root (recommended):
powershell -ExecutionPolicy Bypass -File tools\setup.ps1
37 commits
Python
96.8%
PowerShell
1.4%
Batchfile
1.1%
A Tkinter + OpenGL desktop app for training and viewing 3D Gaussian splats from casual captures. NullSplats wraps COLMAP for camera poses, uses PyTorch + gsplat (plus optional monocular backends) for training/inference, and stores everything in a reproducible cache tree so you can resume scenes without redoing work.
Demo: https://github.com/user-attachments/assets/6bcda99b-5d9d-4960-a759-5008b4bdc766
.ply or .splat.cache/ for repeatable, resumable workflows.NullSplats supports three ways to create splats:
Gsplat 50-view: https://github.com/user-attachments/assets/0a5431de-d146-4192-8305-6ec645161ba1
Gsplat closeup: https://github.com/user-attachments/assets/01245b1e-0098-4ebb-ad6c-00e220ba4e85
DA3 5-view: https://github.com/user-attachments/assets/c5cf7697-eb91-4ee9-9f46-6190622df765
DA3 closeup: https://github.com/user-attachments/assets/b87fa2f9-23c9-4a3b-bba7-82734a069edf
SHARP 1-view: https://github.com/user-attachments/assets/127c5651-a7da-471f-8c65-5c65db2283b2
SHARP closeup: https://github.com/user-attachments/assets/c5599843-46d5-4d2f-ab3d-5881534f3c3e
Side-by-side comparison: https://github.com/user-attachments/assets/00e8449d-0f26-4258-8469-4dc7424652ca
Notes: SHARP’s single-view result is especially impressive. DA3 often nails geometry but can look “weird” or overly transparent; if that improves, it could be a standout few-view option.
Want to discuss development or get support? Open an Issue or join the Discord: https://discord.gg/nP8BMtZ42C
main.py - app entrypoint (Tk root + tabs)nullsplats/
ui/ - Tk UI, tabs, OpenGL viewers, shaders (ui/shaders/*.vert|*.frag)backend/ - frame extraction, COLMAP pipeline, splat trainingutil/ - logging, config, threading helpers and tool path defaultsbuild.bat - portable bundle builderrun.bat - launcher used inside the portable bundlerequirements.txt - Python dependenciesThe app centers around a small core state object (AppState), four UI tabs (Inputs, COLMAP, Training, Exports), and a backend pipeline that handles frame extraction, COLMAP structure-from-motion, and training/inference.
main.py sets up logging, creates AppState, and builds the Tk root in ui/root.py.ui/root.py wires the four tabs and routes scene selection between them.nullsplats/app_state.py owns AppState (config + SceneManager + current scene)nullsplats/backend/io_cache.py defines ScenePaths and metadata read/writeCache layout (per scene):
cache/inputs/<scene_id>/source (original source copy)cache/inputs/<scene_id>/frames_allcache/inputs/<scene_id>/frames_selectedcache/inputs/<scene_id>/metadata.jsoncache/outputs/<scene_id>/sfmcache/outputs/<scene_id>/splatscache/outputs/<scene_id>/rendersnullsplats/backend/scene_manager.py handles scene discovery, selection persistence, and thumbnail caching (thumbnails.db).
ui/root.py builds the ttk.Notebook, instantiates tabs, and coordinates tab changesui/tab_inputs.py + mixinsui/tab_colmap.pyui/tab_training.py + layout/preview mixinsui/tab_exports.pyWizard flows:
ui/tab_inputs_wizard.py (single popup with inputs + training preset + COLMAP options)ui/wizard.pyui/tab_inputs.pyui/tab_inputs_scenes.pyui/tab_inputs_grid.pybackend/video_frames.py, backend/scene_manager.pyui/tab_colmap.py runs SfM and manages COLMAP settings/logsbackend/sfm_pipeline.py (COLMAP CLI)ui/tab_training.py orchestrates training runs, manages logging, and owns preview stateui/tab_training_layout.pyui/tab_training_preview.pybackend/splat_train.py (gsplat training loop)backend/splat_backends/depth_anything3_trainer.py (Depth Anything 3 inference + gs_ply export)ui/tab_exports.py lists checkpoints, opens a preview viewer, and renders turntablesGLCanvas to display .ply checkpoints and imageio for video outputui/gl_canvas.py is the main preview surface
GaussianSplatViewer for live OpenGL displaySplatRenderer (gsplat rasterization) for offline renders and turntablesPreviewPayloadui/gaussian_splat_viewer.py is the OpenGL renderer (instanced quads + shaders)ui/gaussian_splat_camera.py contains camera math helpersui/shaders/gaussian_splat.vert and ui/shaders/gaussian_splat.fragui/render_controls.py (basic controls)ui/advanced_render_controls.py (debug/scale/camera)ui/colmap_camera_panel.py (apply COLMAP poses)util/threading.py runs background tasks and marshals callbacks to the Tk threadutil/logging.py sets a consistent console + file logger under logs/app.logutil/tooling_paths.py resolves default COLMAP and CUDA pathsffmpeg/ffprobe on PATH (video extraction)tools/colmap or user-provided pathtools/depth-anything-3)tools/sharp)Prereqs:
tools/colmap (or set in the UI)ffmpeg/ffprobe on PATHFrom repo root (recommended):
powershell -ExecutionPolicy Bypass -File tools\setup.ps1
37 commits
Python
96.8%
PowerShell
1.4%
Batchfile
1.1%