graphdeco-inria/gaussian-splatting
Original reference implementation of "3D Gaussian Splatting for Real-Time Radiance Field Rendering"
Slowing — last commit 7mo ago
non-standard license (Other); no tests detected…
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
last commit was 7mo ago; no CI workflows detected
- ⚠Slowing — last commit 7mo ago
- ⚠Non-standard license (Other) — review terms
- ⚠No CI workflows detected
- ⚠No test directory detected
- ✓Last commit 7mo ago
- ✓12 active contributors
- ✓Distributed ownership (top contributor 38% of recent commits)
- ✓Other licensed
What would improve this?
- →Use as dependency Concerns → Mixed if: clarify license terms
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/graphdeco-inria/gaussian-splatting)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card
This card auto-renders when someone shares https://repopilot.app/r/graphdeco-inria/gaussian-splatting on X, Slack, or LinkedIn.
Ask AI about graphdeco-inria/gaussian-splatting
Grounded in the actual source code. Pick a starter question or write your own.
Onboarding doc
Onboarding: graphdeco-inria/gaussian-splatting
Generated by RepoPilot · 2026-06-21 · Source
🎯Verdict
WAIT — Slowing — last commit 7mo ago
- Last commit 7mo ago
- 12 active contributors
- Distributed ownership (top contributor 38% of recent commits)
- Other licensed
- ⚠ Slowing — last commit 7mo ago
- ⚠ Non-standard license (Other) — review terms
- ⚠ No CI workflows detected
- ⚠ No test directory detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
⚡TL;DR
This is the official implementation of 3D Gaussian Splatting, a novel-view synthesis technique that represents scenes as 3D Gaussians instead of neural networks. It achieves real-time (≥30 fps) rendering at 1080p by optimizing anisotropic Gaussian covariances during training and using a fast visibility-aware splatting algorithm during inference—solving the speed-quality tradeoff that plagued previous neural radiance field methods. Monolithic Python project organized by function: scene/ handles data loading (COLMAP in colmap_loader.py, cameras.py), gaussian_model.py contains the Gaussian representation, gaussian_renderer/ provides the splatting algorithm, train.py is the main training loop, and utils/ contains metrics and helpers. CUDA code is wrapped via submodules. The arguments/ module centralizes hyperparameter definitions across scripts.
👥Who it's for
Computer vision researchers and graphics engineers who need to train and render novel view synthesis models from multi-view image datasets (COLMAP-based). Specifically useful for those building real-time 3D scene reconstruction systems that require faster training and rendering than NeRF-based approaches.
🌱Maturity & risk
Production-ready and actively maintained by INRIA GRAPHDECO (original authors). The codebase includes pre-trained models (14 GB), evaluation benchmarks, reference implementations, and published papers. No visible CI/CD config in the file list, but the presence of environment.yml and curated training/evaluation scripts (train.py, full_eval.py, render.py) suggests solid stability. This is the reference implementation, not an experimental fork.
Low risk for core algorithmic work, but moderate risk for deployment: CUDA rendering depends on specific PyTorch/CUDA versions (no pinned requirements visible in file list), submodules reference external C++ code (lpipsPyTorch) that may have compatibility issues. No test suite evident in the file structure. The single-author paper and monolithic training pipeline mean bugs in train.py or gaussian_renderer affect all downstream users. Last commit activity not visible from metadata provided.
Active areas of work
Unknown from static file list provided—no git history, PR, or issue data visible. However, the presence of recent additions like exposure handling (Exposure_comparison.png), anti-aliasing (aa_onoff.gif), sparse Adam optimizers (charts/accel_sparse_adam_*), and depth comparisons suggest ongoing refinements beyond the original paper.
🚀Get running
git clone https://github.com/graphdeco-inria/gaussian-splatting.git
cd gaussian-splatting
conda env create -f environment.yml
conda activate gaussian_splatting
python train.py -s /path/to/colmap/dataset -m /path/to/output/model
python render.py -m /path/to/model
First download a COLMAP dataset (T&T+DB provided, 650MB) or prepare your own with colmap_loader.py.
Daily commands:
# Training from COLMAP:
python train.py -s /path/to/colmap_dataset -m outputs/my_model -r 2
# Rendering novel views:
python render.py -m outputs/my_model
# Full evaluation suite:
python full_eval.py -m outputs/my_model
# Real-time viewer:
./viewers/SIBR_viewers (Windows binary, or compile from source)
Checkpoints save to outputs/my_model/point_cloud/iteration_*.ply.
🗺️Map of the codebase
train.py— Entry point for the training pipeline; orchestrates data loading, optimization loop, and Gaussian model updates—essential for understanding the full training workflow.scene/gaussian_model.py— Core abstraction for the Gaussian model state, parameters, and optimization; all rendering and training logic depends on this model definition.gaussian_renderer/__init__.py— Rendering engine that rasterizes Gaussians and computes radiance; critical dependency for both training (loss computation) and inference.render.py— Inference entry point; demonstrates how to load a trained model and perform novel-view synthesis.scene/dataset_readers.py— Loads COLMAP data and camera calibration; bridges the gap between raw input and the training loop's expected data format.utils/loss_utils.py— Defines loss functions (SSIM, L1) used to optimize Gaussians; directly impacts convergence and output quality.arguments/__init__.py— Centralized argument/config parser; controls hyperparameters across training, rendering, and evaluation pipelines.
🧩Components & responsibilities
- Gaussian Model (scene/gaussian_model.py) — Stores and
🛠️How to make changes
Add a new loss function or regularizer
- Define the loss computation in utils/loss_utils.py as a new function (e.g.,
compute_tv_loss()). (utils/loss_utils.py) - Import and instantiate the loss in train.py's main training loop. (
train.py) - Add a command-line argument in arguments/init.py to control loss weight (e.g.,
--tv_weight). (arguments/__init__.py) - Accumulate the loss into the total loss before backprop in train.py. (
train.py)
Add a new Gaussian parameter optimization technique
- Modify the optimizer instantiation in train.py to include new parameter groups or adapt the learning rate schedule. (
train.py) - Implement adaptive densification or pruning logic in scene/gaussian_model.py methods like
densification_postfix()orprune_gaussians(). (scene/gaussian_model.py) - Expose new hyperparameters (e.g., densification threshold, pruning ratio) in arguments/init.py. (
arguments/__init__.py)
Support a new input dataset format
- Create a new reader function in scene/dataset_readers.py (e.g.,
readNerfDataset()) that parses your format and returns camera list and image paths. (scene/dataset_readers.py) - Add a format identifier (e.g.,
--source_path_format) in arguments/init.py. (arguments/__init__.py) - Update the dataset instantiation logic in train.py to call your new reader based on the format flag. (
train.py)
Add custom rendering post-processing or export
- Create a new utility function in utils/image_utils.py for post-processing (e.g., tone mapping, filtering). (
utils/image_utils.py) - Call the post-processor in render.py after rendering and before saving. (
render.py) - Add command-line flags in arguments/init.py to toggle post-processing options. (
arguments/__init__.py)
🔧Why these technologies
- CUDA / PyTorch — Enables GPU-accelerated Gaussian rasterization and differentiable rendering; critical for real-time performance.
- Spherical Harmonics (SH) — Compact representation of view-dependent color; balances expressiveness and parameter efficiency for real-time rendering.
- COLMAP format — Industry-standard structure-from-motion output; allows training on arbitrary photographic datasets without custom preprocessing.
- Adam optimizer — Adaptive per-parameter learning rates; essential for stable training of heterogeneous Gaussian parameters (position, covariance, SH).
⚖️Trade-offs already made
-
Gaussian splatting vs. implicit neural fields (NeRF)
- Why: Splatting provides real-time rendering and interpretable geometry; implicit fields are slower but may generalize better.
- Consequence: Fast inference at cost of explicit memory footprint and potential artifacts at occlusion boundaries.
-
Densification via cloning and splitting
- Why: Adaptive Gaussian count avoids over-parameterization; heuristics (gradient magnitude) are simple and differentiable.
- Consequence: Densification decisions are greedy and may miss optimal Gaussian placements; requires tuning of densification thresholds.
-
Spherical harmonics over neural color networks
- Why: SH reduces per-Gaussian parameters; enables fast view-dependent shading without MLP evaluation.
- Consequence: SH has limited expressiveness for complex view-dependent effects; may require higher degree (slower) for photorealistic materials.
🚫Non-goals (don't propose these)
- Real-time training; training requires hours of GPU computation.
- Multi-GPU distributed training support (single-GPU only in reference implementation).
- Handling dynamic scenes; assumes static geometry.
- Unbounded outdoor scenes; best suited to bounded indoor/object captures.
- Cross-dataset generalization; must retrain per-scene from scratch.
🪤Traps & gotchas
- COLMAP dataset format: expects cameras.json, images/, and sparse/0/ with cameras.bin, images.bin, points3D.bin—if missing, dataset_readers.py silently fails. 2. SH degree: must match between training and rendering; querying wrong degree crashes rendering. 3. Density control thresholds (arguments.py: densify_grad_threshold, densify_from_iter, densify_until_iter) are dataset-dependent; defaults tuned for Mip-NeRF 360, not arbitrary captures. 4. CUDA memory: 3D Gaussians explode in count (10M+ points possible); no checkpointing, so OOM requires reducing resolution or densification params. 5. No built-in validation split—train.py uses entire dataset unless explicitly held out before training.
🏗️Architecture
💡Concepts to learn
- Spherical Harmonics (SH) — Used in gaussian_model.py to represent view-dependent appearance (specularity, reflections) without a neural network—critical for photorealism while maintaining fast rendering.
- Anisotropic Gaussian Covariance — The core innovation in this repo: instead of isotropic point clouds, each Gaussian has a full 3x3 covariance matrix optimized per-iteration. This allows thin structures (leaves, walls) to be represented efficiently.
- Density Control (Pruning, Splitting, Cloning) — Interleaved optimization in train.py that adaptively adds/removes Gaussians based on gradients, avoiding both under- and over-representation. Enables convergence 5-10x faster than NeRF.
- Screen-Space Rasterization & Splatting — gaussian_renderer/ implements tile-based forward splatting (projection to screen space, accumulation via alpha blending), not backward ray tracing. This is why rendering hits 30+ fps at 1080p.
- COLMAP Structure-from-Motion — colmap_loader.py consumes COLMAP's sparse reconstructions (cameras.bin, images.bin, points3D.bin format). Understanding this format is mandatory to use the training pipeline on real data.
- Exponential Moving Average (EMA) for Loss Smoothing — train.py uses EMA to track Gaussian gradients for densification decisions. High EMA variance indicates where to split; low variance means safe to prune—elegant adaptive mechanism.
- Adam Optimizer with Per-Parameter Learning Rates — gaussian_model.py uses different LR for position (0.00016), scale (0.005), rotation (0.001), SH (0.0025)—careful tuning per parameter type is essential for stable convergence without manual intervention.
🔗Related repos
NVlabs/instant-ngp— Predecessor instant NeRF technique using multiresolution hash grids; established the speed-quality frontier that Gaussian Splatting improved upon.nerfstudio-project/nerfstudio— Modern NeRF training framework that now integrates Gaussian Splatting as a backend option alongside NeRF variants; ecosystem for reproducible 3D research.autonomousvision/mipnerf360— Mip-NeRF 360 dataset and method; the unbounded scene benchmark used to evaluate Gaussian Splatting's real-time improvements.colmap/colmap— Structure-from-Motion engine that produces the sparse point clouds and camera poses consumed by this repo's colmap_loader.py.graphdeco-inria/gaussian-splatting-web— Official JavaScript viewer for real-time Gaussian Splatting on the web; companion deployment target for trained models.
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add unit tests for Gaussian model operations (scene/gaussian_model.py)
The repo lacks any test suite despite having critical mathematical operations in gaussian_model.py (spherical harmonics, covariance calculations, densification logic). A new contributor could add pytest-based unit tests for core Gaussian operations, improving numerical stability confidence and serving as documentation for expected behavior. This is particularly valuable given the repo's sensitivity to numerical precision in 3D reconstruction.
- [ ] Create tests/ directory with conftest.py
- [ ] Add test_gaussian_model.py testing SH evaluation, covariance computation, and densification thresholds from scene/gaussian_model.py
- [ ] Add test_sh_utils.py for spherical harmonics functions in utils/sh_utils.py
- [ ] Add test_graphics_utils.py for matrix operations in utils/graphics_utils.py
- [ ] Document how to run tests in README.md
Add data loader validation and input sanitization (scene/dataset_readers.py)
The dataset_readers.py handles COLMAP data loading but has no explicit validation for malformed inputs. A new contributor could add checks for invalid camera parameters, missing pose files, and corrupted image paths with informative error messages. This prevents silent failures during training and improves the user experience when datasets are incomplete or improperly formatted.
- [ ] Add validation functions to scene/dataset_readers.py for COLMAP camera intrinsics (focal length bounds, resolution validity)
- [ ] Add checks for missing required files (cameras.bin, images.bin, points3D.bin) with clear error messages
- [ ] Add image file existence verification before training starts
- [ ] Create a test dataset validation script or integrate into convert.py with a --validate flag
- [ ] Document expected COLMAP output format and validation rules in README.md
Add GitHub Actions CI workflow for training pipeline validation
The repo has no CI/CD pipeline to catch training regressions, CUDA compatibility issues, or dependency conflicts. A new contributor could add a GitHub Actions workflow that runs train.py on a tiny synthetic dataset with assertions on output quality metrics (PSNR/SSIM/LPIPS from metrics.py). This catches breaking changes early and gives confidence in cross-platform compatibility.
- [ ] Create .github/workflows/training_pipeline.yml with Ubuntu GPU runner (using accessible CUDA image)
- [ ] Add step to generate or use a minimal test dataset (or create a tiny synthetic one in test_data/)
- [ ] Run train.py with reduced iterations and early stopping to complete in <10 minutes
- [ ] Assert output render.py results meet minimum PSNR/SSIM thresholds using metrics.py
- [ ] Add workflow status badge to README.md
- [ ] Document in CONTRIBUTING.md how contributors should ensure CI passes
🌿Good first issues
- Add per-scene hyperparameter presets: Create scene/presets.json with dataset-specific densification thresholds and learning rates for common datasets (Blender, Mip-NeRF 360, Tanks&Temples). Many users blindly use defaults and get poor results on out-of-distribution data.
- Implement checkpoint resumption: train.py currently doesn't support --resume flag. Add logic to restore Gaussian state, iteration count, and optimizer from the latest checkpoint—useful for long training runs and grid searches.
- Write integration tests for COLMAP loader: Add tests/ directory with fixture data (minimal COLMAP reconstruction, 2-3 images) and test that colmap_loader.py correctly parses cameras and point clouds. Currently no test coverage for this critical I/O path.
- Document SH coefficient interpretation: Add docstrings to gaussian_model.py explaining spherical harmonics degree meanings and how view-dependent appearance emerges. First-time users are confused by the sheer number of parameters.
- Add tensorboard logging: train.py prints metrics to console only. Integrate tensorboard to log loss curves, point cloud count over time, and rendered validation views—standard practice missing from this codebase.
⭐Top contributors
Click to expand
Top contributors
- @Snosixtyboo — 38 commits
- @bkerbl — 32 commits
- @alanvinx — 15 commits
- [@Bernhard Kerbl](https://github.com/Bernhard Kerbl) — 5 commits
- @graphdeco — 2 commits
📝Recent commits
Click to expand
Recent commits
54c035f— fix submodule name in environment.yml (alanvinx)3dc0b75— fix training report, add missing dependency (alanvinx)9e1c2c6— fix asset name in results.md (alanvinx)8091682— Merge update readme (alanvinx)dd795e2— added missing parameters for remote viewer (alanvinx)9d721df— Update README.md (alanvinx)182afc9— New release: issues fixed and integrated training speed acceleration. (alanvinx)a2a91d9— fix depth file path for synthetic scenes (alanvinx)9375aa7— added NeRF synthetic datasets training using depth regularization (alanvinx)f689f41— update SIBR viewer commit, update readme. (alanvinx)
🔒Security observations
The Gaussian Splatting repository is a research/academic codebase with moderate security posture. No critical vulnerabilities were identified in the visible structure. Primary concerns are: (1) absence of explicit dependency pinning in a requirements.txt, (2) potential path traversal risks in data loading modules without evidence of input validation, (3) loose management of git submodules, and (4) lack of security documentation. The codebase appears to be primarily a scientific implementation without web-facing components or databases, which reduces the attack surface. Recommendations focus on hardening input validation, explicitly pinning dependencies, and establishing security practices for community contributions.
- Medium · Missing Dependency Manifest —
Repository root / environment.yml. No requirements.txt or setup.py file detected in the repository root. The environment.yml file is present but Python dependency versions are not explicitly pinned, which may lead to inconsistent builds and potential installation of vulnerable dependency versions. Fix: Create a requirements.txt file with pinned versions for all Python dependencies. Usepip freeze > requirements.txtand verify all versions are secure using tools likesafetyorpip-audit. - Low · Potential Path Traversal in Data Loading —
scene/colmap_loader.py, scene/dataset_readers.py. The codebase includes data loading functionality (scene/colmap_loader.py, scene/dataset_readers.py) that may accept file paths from user input. Without proper validation, this could lead to path traversal vulnerabilities when loading datasets. Fix: Implement strict path validation usingos.path.abspath()and verify paths are within the expected data directory. Usepathlib.Path.resolve()to prevent symbolic link attacks. - Low · Lack of Input Validation in Training Script —
train.py, arguments/__init__.py. The train.py script accepts command-line arguments and configuration parameters. While arguments are defined in arguments/init.py, there is no visible validation of numeric ranges, file existence checks, or type enforcement that could prevent unexpected behavior. Fix: Implement comprehensive input validation for all command-line arguments including type checking, range validation for numeric parameters, and verification of file existence for input paths. - Low · Third-party Submodules Without Version Pinning —
.gitmodules, submodules/. The .gitmodules file indicates use of git submodules which may pull from external repositories. Without version/commit pinning, submodules could be updated to unvetted versions. Fix: Pin all submodule commits explicitly in .gitmodules. Regularly audit submodule updates and verify their security. Document the purpose of each submodule. - Low · No Security Policy or License Clarity —
Repository root. While LICENSE.md exists, there is no SECURITY.md file or security policy documented for reporting vulnerabilities. README.md provides academic attribution but no security guidance. Fix: Create a SECURITY.md file documenting the security policy, how to report vulnerabilities responsibly, and any security considerations for users deploying this code.
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/graphdeco-inria/gaussian-splatting shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live graphdeco-inria/gaussian-splatting
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/graphdeco-inria/gaussian-splatting.
What it runs against: a local clone of graphdeco-inria/gaussian-splatting — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in graphdeco-inria/gaussian-splatting | Confirms the artifact applies here, not a fork |
| 2 | License is still Other | Catches relicense before you depend on it |
| 3 | Default branch main exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 234 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of graphdeco-inria/gaussian-splatting. If you don't
# have one yet, run these first:
#
# git clone https://github.com/graphdeco-inria/gaussian-splatting.git
# cd gaussian-splatting
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of graphdeco-inria/gaussian-splatting and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "graphdeco-inria/gaussian-splatting(\\.git)?\\b" \\
&& ok "origin remote is graphdeco-inria/gaussian-splatting" \\
|| miss "origin remote is not graphdeco-inria/gaussian-splatting (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Other)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Other\"" package.json 2>/dev/null) \\
&& ok "license is Other" \\
|| miss "license drift — was Other at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "train.py" \\
&& ok "train.py" \\
|| miss "missing critical file: train.py"
test -f "scene/gaussian_model.py" \\
&& ok "scene/gaussian_model.py" \\
|| miss "missing critical file: scene/gaussian_model.py"
test -f "gaussian_renderer/__init__.py" \\
&& ok "gaussian_renderer/__init__.py" \\
|| miss "missing critical file: gaussian_renderer/__init__.py"
test -f "render.py" \\
&& ok "render.py" \\
|| miss "missing critical file: render.py"
test -f "scene/dataset_readers.py" \\
&& ok "scene/dataset_readers.py" \\
|| miss "missing critical file: scene/dataset_readers.py"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 234 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~204d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/graphdeco-inria/gaussian-splatting"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.
Similar Python repos
Other mixed-signal Python repos by stars.
Embed this chat in your README →
Drop this iframe anywhere — the widget runs against the same live analysis cache as the main app.
<iframe src="https://repopilot.app/embed/graphdeco-inria/gaussian-splatting" width="100%" height="500" style="border:1px solid #d0d7de; border-radius:8px;" allow="microphone" loading="lazy" ></iframe>