NoteSource

Paper: arXiv:2308.04079 · Project page & code · DOI: 10.1145/3592433. Authors: Bernhard Kerbl, Georgios Kopanas, Thomas Leimkühler, George Drettakis (Inria / Université Côte d’Azur / MPI). Published in ACM Transactions on Graphics 42(4), July 2023.

TL;DR

3D Gaussian Splatting (3DGS) is a method for novel-view synthesis: given photos of a static scene plus the camera poses recovered by Structure-from-Motion, it builds a 3D representation you can render from any new viewpoint. Its headline achievement is being the first method to deliver state-of-the-art visual quality and real-time rendering (≥ 30 fps, in practice 100+ fps) at 1080p for unbounded, complete real-world scenes, while training in tens of minutes rather than hours or days.

It replaces the neural network at the heart of NeRF with an explicit cloud of millions of anisotropic 3D Gaussians — differentiable, semi-transparent “blobs,” each with a position, a shape (covariance), an opacity, and a view-dependent color. Three pillars:

  1. A 3D Gaussian scene representation that keeps the continuous/differentiable properties of volumetric radiance fields while being explicit enough to rasterize extremely fast, wasting no computation on empty space.
  2. Optimization with adaptive density control — gradient descent on the Gaussians’ parameters, interleaved with clone/split/prune steps that grow the right level of detail where needed.
  3. A fast, differentiable, tile-based rasterizer that sorts all splats once per frame with a GPU radix sort, respects visibility order via α-blending, and back-propagates to an unlimited number of Gaussians per pixel.

The result equals or beats Mip-NeRF360 (previous quality SOTA: ~48 GPU-hours to train, ~10 s/frame to render) while training in 35–45 minutes and rendering in real time.

Introduction — The Problem and the Idea

The tension the paper resolves

By 2023 novel-view synthesis had split into two camps, each forced to give something up:

  • Continuous / neural representations (NeRF and descendants). Optimize an MLP queried by volumetric ray-marching. Continuity aids optimization and gives beautiful results, but rendering requires stochastic sampling of many points per ray — slow and noisy. The quality leader, Mip-NeRF360, needed up to 48 hours of training and rendered at seconds per frame.
  • Fast grid / hash methods (InstantNGP, Plenoxels). Storing interpolatable features in voxel/hash grids cut training to minutes and reached interactive (~10–15 fps) rates, but they still ray-march, still struggle with empty space, and their quality is capped by the structured acceleration grid.

Nobody could get all three at once — SOTA quality, fast training, and real-time 1080p rendering of full scenes. That is the gap 3DGS closes.

The core insight

Meshes and points map cleanly onto fast GPU rasterization. NeRFs win on quality because volumetric α-blending is a forgiving, gradient-friendly image-formation model. 3DGS asks: what primitive is simultaneously (a) a differentiable volumetric element and (b) trivially and cheaply rasterizable?

The answer is an anisotropic 3D Gaussian — a smooth differentiable volumetric bump (so optimization behaves like a radiance field) that projects to a 2D Gaussian “splat” blendable with ordinary α-compositing (so rendering behaves like point rasterization). Empty space contains no Gaussians, so no compute is wasted there.

The three contributions

  1. Anisotropic 3D Gaussians as a high-quality, unstructured representation of radiance fields.
  2. An optimization method for Gaussian properties, interleaved with adaptive density control.
  3. A fast, differentiable, visibility-aware GPU renderer supporting anisotropic splatting and efficient backpropagation.

Input is the same as NeRF’s: SfM-calibrated cameras, which produce a sparse point cloud for free. Unlike most prior point-based methods, 3DGS needs only SfM points — no Multi-View Stereo. On synthetic data it even works from random initialization. Converged scenes hold 1–5 million Gaussians.

Overview — The Pipeline End to End

The method takes images + SfM cameras (and the free sparse cloud), builds 3D Gaussians (Section 1.5), optimizes them with adaptive density control (Section 1.6), and renders them with a fast tile-based rasterizer (Section 1.7). The optimization loop uses the same fast renderer it will later use for real-time viewing — which is why training is competitive with the fastest methods.

The following flowchart reconstructs Figure 2 (the paper’s system overview):

flowchart LR
    A["Input images<br/>of a static scene"] --> B["SfM camera<br/>calibration"]
    B --> C["Sparse SfM<br/>point cloud"]
    C --> D["Initialize 3D Gaussians<br/>(position, covariance, opacity, SH color)"]

    subgraph LOOP ["Training loop (interleaved)"]
        direction TB
        D --> E["Projection to 2D"]
        E --> F["Differentiable<br/>tile-based rasterizer"]
        F --> G["Rendered image I"]
        G --> H["Compare to ground-truth view<br/>L = (1-lambda)*L1 + lambda*L_D-SSIM"]
        H --> I["Backprop then Adam step<br/>(update all Gaussian params)"]
        I --> J{"Refinement<br/>iteration?"}
        J -- "yes" --> K["Adaptive density control:<br/>clone, split, prune"]
        J -- "no" --> E
        K --> E
    end

    G --> L["Trained 3D Gaussians"]
    L --> M["Real-time free-view<br/>navigation (100+ fps)"]
Figure 1: System overview (reconstruction of the paper’s Fig. 2). SfM points seed a set of 3D Gaussians; an interleaved loop of differentiable rasterization, loss, backprop, and adaptive density control produces a trained model rendered in real time.

Differentiable 3D Gaussian Splatting — The Representation

Why Gaussians, and how they are defined

The goal: a primitive that inherits differentiable-volumetric properties yet is unstructured and explicit for fast rendering — and that works from normal-free SfM points. 3D Gaussians fit. A Gaussian is defined by a full 3D covariance \(\Sigma\) in world space, centered at mean \(\mu\):

\[ G(x) = e^{-\frac{1}{2}(x-\mu)^{T}\,\Sigma^{-1}\,(x-\mu)}. \tag{4}\]

In blending, \(G(x)\) is multiplied by the Gaussian’s opacity \(\alpha\).

Projecting 3D Gaussians to 2D (EWA splatting)

For rendering, each Gaussian becomes a 2D splat. Following Zwicker et al.’s EWA framework, given a viewing transform \(W\), the camera-space covariance is:

\[ \Sigma' = J\,W\,\Sigma\,W^{T}\,J^{T}, \tag{5}\]

where \(J\) is the Jacobian of the affine approximation of the projective transform. Dropping the third row and column of \(\Sigma'\) yields a \(2\times2\) covariance — a proper 2D Gaussian splat.

A parameterization that stays valid under gradient descent

You cannot optimize the raw entries of \(\Sigma\) directly: a covariance is only physically meaningful when positive semi-definite, and unconstrained gradient steps produce invalid matrices. Since \(\Sigma\) describes an ellipsoid, factor it into a rotation and a scale:

\[ \Sigma = R\,S\,S^{T}\,R^{T}. \tag{6}\]

Stored separately and optimized independently: a 3D scale vector \(s\) (→ diagonal \(S\)) and a quaternion \(q\) (normalized → rotation \(R\)). As expressive as a raw covariance, but always valid. To avoid autodiff overhead on this hot path, all gradients are derived explicitly (Section 1.12).

TipThe payoff

Anisotropic Gaussians can hug real surfaces — large flat blobs for big homogeneous regions, thin elongated ones for fine structures — giving a compact yet accurate representation (the paper’s Fig. 3 shrinks Gaussians by 60% to expose their anisotropy; see the project page).

The full per-Gaussian parameter set

Parameter Symbol Role
Position (mean) \(\mu\) / \(p\) Where the blob sits in world space
Scale \(s\) (3D vector) Ellipsoid axis lengths → \(S\)
Rotation \(q\) (quaternion) Ellipsoid orientation → \(R\)
Opacity \(\alpha\) Blending weight (sigmoid-activated)
Color SH coefficients View-dependent appearance via spherical harmonics

Optimization with Adaptive Density Control

The optimization step

Iterate: render a training view, compare to the captured image, back-propagate, step. Because 3D→2D projection is ambiguous, the optimizer must create, destroy, and move geometry. Key choices:

  • Optimizer: Adam SGD, with custom CUDA kernels on the critical path (rasterization is the bottleneck).
  • Activations: sigmoid on \(\alpha\) (keeps it in \([0,1)\) with smooth gradients); exponential on covariance scale.
  • Initial covariance: isotropic, axis length = mean distance to the 3 nearest SfM points.
  • LR schedule: exponential decay (à la Plenoxels), applied to positions only.
  • Loss: \(\mathcal{L}_1\) + D-SSIM:

\[ \mathcal{L} = (1-\lambda)\,\mathcal{L}_1 + \lambda\,\mathcal{L}_{\text{D-SSIM}}, \qquad \lambda = 0.2. \tag{7}\]

Adaptive control of Gaussians — clone, split, prune

Every 100 iterations (after warm-up), density is adjusted. Two failure modes are targeted, and both show up as large view-space positional gradients (the optimizer straining to move Gaussians):

  • Under-reconstruction — missing geometry; small Gaussians can’t cover a region.
  • Over-reconstruction — one big Gaussian sprawling over detailed geometry.

Gaussians with average view-space position-gradient magnitude above \(\tau_{pos} = 0.0002\) are densified:

  • Under-reconstruction → CLONE: copy the small Gaussian, shift the copy along the positional gradient. Adds volume and a Gaussian.
  • Over-reconstruction → SPLIT: replace the large Gaussian with two, dividing scale by \(\phi = 1.6\), sampling positions using the original as a PDF. Conserves volume, adds a Gaussian.

Pruning / count control. Remove Gaussians with \(\alpha < \epsilon_\alpha\). To fight near-camera “floaters,” every N = 3000 iterations \(\alpha\) is reset near zero; the optimizer re-raises \(\alpha\) only where needed, and culling removes the rest. Oversized world-space or viewspace Gaussians are periodically removed. Gaussians stay Euclidean primitives at all times — no space warping/contraction (unlike Mip-NeRF360 or Plenoxels).

Densification logic (reconstruction of Fig. 4 / Algorithm 1):

flowchart TD
    A["Refinement iteration<br/>(every 100 iters)"] --> B{"For each Gaussian"}
    B --> C{"alpha &lt; eps_a<br/>or too large?"}
    C -- "yes" --> D["Prune / remove"]
    C -- "no" --> E{"View-space pos.<br/>gradient &gt; tau_pos?"}
    E -- "no" --> F["Leave unchanged"]
    E -- "yes" --> G{"Scale ||S|| &gt; tau_S?"}
    G -- "large<br/>(over-reconstruction)" --> H["SPLIT into 2<br/>scale / phi (1.6)<br/>sample new positions"]
    G -- "small<br/>(under-reconstruction)" --> I["CLONE<br/>copy + move along<br/>positional gradient"]
Figure 2: Adaptive density control (reconstruction of the paper’s Fig. 4). High view-space positional gradient triggers densification; large Gaussians split (over-reconstruction), small ones clone (under-reconstruction); transparent or oversized Gaussians are pruned.

The overall training loop (Algorithm 1):

flowchart TD
    A["M = SfM points (positions)"] --> B["S, C, A = InitAttributes()<br/>covariances, colors, opacities"]
    B --> C["i = 0"]
    C --> D{"not converged?"}
    D -- "no" --> Z["Done then trained model"]
    D -- "yes" --> E["V, GT = SampleTrainingView()"]
    E --> F["I = Rasterize(M,S,C,A,V)  (Alg. 2)"]
    F --> G["L = Loss(I, GT)"]
    G --> H["M,S,C,A = Adam(grad L)"]
    H --> I{"IsRefinementIteration(i)?"}
    I -- "yes" --> J["Prune (alpha&lt;eps or too large)<br/>+ Densify (split / clone)"]
    I -- "no" --> K["i = i + 1"]
    J --> K
    K --> D
Figure 3: Optimization and densification loop (Algorithm 1). Initialize from SfM points; each iteration samples a view, rasterizes, computes the loss, and steps Adam; refinement iterations prune and densify.

Fast Differentiable Rasterizer for Gaussians

Design goals: fast rendering; fast sorting for approximate α-blending (including anisotropic splats); and no hard cap on how many splats can receive gradients (a Pulsar limitation).

Tile-based forward pass

  1. Tile the screen into 16×16 pixel tiles.
  2. Cull against the view frustum — keep Gaussians whose 99% confidence ellipsoid intersects it; a guard band trivially rejects unstable extreme-position Gaussians.
  3. Instantiate each Gaussian once per overlapped tile, with a 64-bit key: low 32 bits = view-space depth, high bits = tile ID.
  4. Sort all instances with a single GPU radix sort. Whole-image depth order resolved at once — no per-pixel sorting. Blending is therefore approximate, but error vanishes as splats approach pixel size.
  5. Build per-tile ranges (one thread per key, comparing high bits with neighbors).
  6. Rasterize: one thread block per tile; threads collaboratively load Gaussians into shared memory; each pixel walks its list front-to-back, accumulating color and \(\alpha\), stopping when \(\alpha\) saturates; the tile terminates when all pixels saturate.

Backward pass without storing per-pixel lists

  • Reuse the sorted array and per-tile ranges, traversing back-to-front.
  • A pixel processes a point only if its depth ≤ the depth of the last point that contributed in the forward pass.
  • Instead of storing every intermediate opacity, each pixel stores only the total accumulated \(\alpha\), and the backward pass divides by each point’s \(\alpha\) to recover the coefficients.

Because the only stopping criterion is \(\alpha\)-saturation (not a fixed count), the method handles arbitrary depth complexity with no scene-specific tuning — critical to quality (the ablation capping gradient depth to 10 splats lost ~11 dB PSNR).

Rasterizer (Algorithm 2):

flowchart TD
    A["RASTERIZE(w, h, M, S, C, A, V)"] --> B["CullGaussian(p, V)<br/>frustum + guard band"]
    B --> C["M', S' = ScreenspaceGaussians(M,S,V)<br/>EWA projection to 2D"]
    C --> D["T = CreateTiles(w, h)  (16x16)"]
    D --> E["L, K = DuplicateWithKeys(M', T)<br/>key = tileID and depth"]
    E --> F["SortByKeys(K, L)<br/>single global GPU radix sort"]
    F --> G["R = IdentifyTileRanges(T, K)"]
    G --> H["for each tile t, each pixel i:<br/>BlendInOrder front-to-back<br/>until alpha saturates"]
    H --> I["return image I"]
Figure 4: GPU software rasterization of 3D Gaussians (Algorithm 2). Cull, project to screen space, tile, duplicate-with-keys, one global radix sort, identify tile ranges, then blend front-to-back per tile until alpha saturates.

Numerical stability

Reconstructing opacities by division risks divide-by-zero. Safeguards: skip blending with \(\alpha < \epsilon\) (\(\epsilon = \tfrac{1}{255}\)), clamp \(\alpha \le 0.99\), and — before adding a Gaussian — stop front-to-back blending if accumulated opacity would exceed 0.9999.

Implementation, Results, and Evaluation

Implementation details

  • Stack: Python + PyTorch; custom CUDA kernels for rasterization; NVIDIA CUB radix sort; interactive viewer on SIBR.
  • Resolution warm-up: start at ¼ resolution, upsample after 250 and 500 iterations.
  • Progressive SH: optimize only the zero-order (diffuse) band first, add one band every 1000 iterations up to 4 bands — prevents diffuse-color corruption on partial-hemisphere captures.
  • Hardware: single NVIDIA A6000 (Mip-NeRF360 trained on A100s).

Quantitative results — real scenes (Table 1)

13 real scenes across Mip-NeRF360, Tanks & Temples, Deep Blending; same hyperparameters; every 8th photo held out; SSIM ↑, PSNR ↑, LPIPS ↓.

Method Mip360 SSIM↑ PSNR↑ LPIPS↓ Train FPS Mem T&T SSIM↑ PSNR↑ LPIPS↓ Train FPS Mem DeepBlend SSIM↑ PSNR↑ LPIPS↓ Train FPS Mem
Plenoxels 0.626 23.08 0.463 25m49s 6.79 2.1GB 0.719 21.08 0.379 25m5s 13.0 2.3GB 0.795 23.06 0.510 27m49s 11.2 2.7GB
INGP-Base 0.671 25.30 0.371 5m37s 11.7 13MB 0.723 21.72 0.330 5m26s 17.1 13MB 0.797 23.62 0.423 6m31s 3.26 13MB
INGP-Big 0.699 25.59 0.331 7m30s 9.43 48MB 0.745 21.92 0.305 6m59s 14.4 48MB 0.817 24.96 0.390 8m 2.79 48MB
Mip-NeRF360 0.792 27.69 0.237 48h 0.06 8.6MB 0.759 22.22 0.257 48h 0.14 8.6MB 0.901 29.40 0.245 48h 0.09 8.6MB
Ours-7K 0.770 25.60 0.279 6m25s 160 523MB 0.767 21.20 0.280 6m55s 197 270MB 0.875 27.78 0.317 4m35s 172 386MB
Ours-30K 0.815 27.21 0.214 41m33s 134 734MB 0.841 23.14 0.183 26m54s 154 411MB 0.903 29.41 0.243 36m2s 137 676MB

Ours-30K matches or beats Mip-NeRF360’s quality while training in ~35–45 min (vs. 48 h) and rendering at 130–150+ fps (vs. 0.06–0.14 fps). Ours-7K (≈5–7 min) already surpasses InstantNGP/Plenoxels on most metrics at 160–197 fps. The cost is memory: hundreds of MB vs. tens of MB for grid/hash methods.

Quantitative results — synthetic Blender (Table 2)

From 100K random Gaussians (no SfM), pruned to 6–10K meaningful ones, final 200–500K, rendered at 180–300 fps.

Mic Chair Ship Materials Lego Drums Ficus Hotdog Avg.
Plenoxels 33.26 33.98 29.62 29.14 34.10 25.35 31.83 36.81 31.76
INGP-Base 36.22 35.00 31.10 29.78 36.39 26.02 33.51 37.40 33.18
Mip-NeRF 36.51 35.14 30.41 30.71 35.70 25.48 33.29 37.48 33.09
Point-NeRF 35.95 35.40 30.97 29.61 35.04 26.06 36.13 37.30 33.30
Ours-30K 35.36 35.83 30.80 30.00 35.78 26.15 34.87 37.72 33.32

3DGS posts the best average PSNR (33.32) even from random init.

Compactness. Against Zhang et al. 2022, 3DGS breaks even on PSNR in 2–4 minutes using ~¼ the point count, at ~3.8 MB vs. 9 MB (2 SH degrees for fairness).

NoteQualitative figures

Fig. 1 (teaser), Fig. 5 (side-by-side comparisons on Bicycle/Garden/Stump/Counter/Room/Playroom/DrJohnson/Truck/Train), and Fig. 6 (7K-vs-30K convergence) are hosted on the project page, which also holds the supplemental video with far-from-input camera paths.

Ablations (Table 3)

  • Initialization from SfM. Random init still avoids total failure but degrades in the background and leaves un-removable floaters (Fig. 7).
  • Densification: clone vs. split. Split helps background reconstruction; clone aids thin structures and convergence (Fig. 8).
  • Unlimited gradient depth. Capping gradients to N = 10 front-most splats caused unstable optimization and −11 dB PSNR on Truck (Fig. 9).
  • Anisotropic covariance. Replacing full covariance with a single isotropic radius significantly lowers quality (Fig. 10).
  • Spherical harmonics. SH improves PSNR by modeling view-dependent effects.

Limitations

  • Artifacts in poorly observed regions (elongated/“splotchy” Gaussians) — Mip-NeRF360 also struggles (Figs. 11, 12).
  • Popping artifacts for large Gaussians, aggravated by guard-band rejection and simple global-sort visibility; anti-aliasing and principled culling are future work.
  • No regularization yet.
  • Memory: peak training memory can exceed 20 GB (unoptimized prototype); models are hundreds of MB + 30–500 MB rasterizer overhead.
  • Very large scenes may need a lower position learning rate.

Discussion and Conclusions

3DGS is the first method to deliver truly real-time, high-quality radiance-field rendering across diverse scenes and capture styles, with training competitive with the fastest prior methods. Central lesson: a continuous representation is not strictly necessary for fast, high-quality radiance-field training — an explicit 3D-Gaussian primitive preserves the volumetric properties that make optimization work while enabling direct, fast, splat-based rasterization.

~80% of training time is still Python/PyTorch (only rasterization is CUDA); porting the rest to CUDA should yield large further speedups. Mesh reconstruction from Gaussians is flagged as intriguing future work.

Intuition Cheat-Sheet

  • A Gaussian = a fuzzy, colored, semi-transparent ellipsoidal blob. Millions of them, overlapping, are the scene.
  • Training = sculpting a cloud of blobs so that, α-blended from every training camera, they reproduce the photos.
  • Density control = automatic level-of-detail. Missing detail → clone; over-worked blob → split; transparent/oversized → prune.
  • Rendering = sort once, blend front-to-back per 16×16 tile. No ray-marching, no network in the loop, no wasted work in empty space — hence 100+ fps.
  • Why it beats NeRF on speed: NeRF queries a network at many random samples per ray; 3DGS rasterizes explicit primitives the GPU loves, sharing the same α-blending math, so quality need not suffer.

Key Symbols and Hyperparameters

Symbol / term Meaning Value / note
\(\mu\), \(p\) Gaussian mean / position optimized
\(\Sigma\) 3D covariance (world space) \(= R S S^T R^T\)
\(s\), \(q\) scale vector, rotation quaternion stored separately; \(q\) normalized
\(\alpha\) opacity sigmoid-activated
SH spherical-harmonic color 4 bands, added progressively
\(\Sigma'\) 2D covariance (screen) \(= J W \Sigma W^T J^T\)
\(\lambda\) D-SSIM loss weight 0.2
\(\tau_{pos}\) densification gradient threshold 0.0002
\(\phi\) split scale-division factor 1.6
\(\epsilon_\alpha\) prune-opacity threshold small
\(N\) (opacity reset) \(\alpha\) reset interval every 3000 iters
densify interval refinement cadence every 100 iters
tile size rasterizer tile 16×16 px
radix key sort key 64-bit: [tile ID · depth]
\(\epsilon\) (stability) min blend \(\alpha\) 1/255
Gaussian count converged real scenes 1–5 million

Appendix A — Explicit Gradient Derivation

Autodiff is avoided on the hot path; gradients are derived by hand. With \(\Sigma / \Sigma'\) the world/view covariances, \(q\) rotation, \(s\) scale, \(W\) view transform, \(J\) the projective-affine Jacobian:

\[ \frac{d\Sigma'}{ds} = \frac{d\Sigma'}{d\Sigma}\frac{d\Sigma}{ds}, \qquad \frac{d\Sigma'}{dq} = \frac{d\Sigma'}{d\Sigma}\frac{d\Sigma}{dq}. \tag{8}\]

Let \(U = JW\), with \(\Sigma'\) the symmetric upper-left \(2\times2\) block of \(U\Sigma U^T\). Then

\[ \frac{\partial \Sigma'}{\partial \Sigma_{ij}} = \begin{pmatrix} U_{1,i}U_{1,j} & U_{1,i}U_{2,j} \\ U_{1,j}U_{2,i} & U_{2,i}U_{2,j} \end{pmatrix}. \]

Writing \(M = RS\) so \(\Sigma = MM^T\), the shared factor is \(\dfrac{d\Sigma}{dM} = 2M^T\). For scale, \(\dfrac{\partial M_{i,j}}{\partial s_k} = R_{i,k}\) if \(j=k\), else \(0\). Rotation derivatives follow from the unit-quaternion-to-matrix map \(R(q)\), yielding closed forms for \(\partial M / \partial q_r, \partial q_i, \partial q_j, \partial q_k\). Quaternion-normalization gradients are straightforward. Takeaway: every parameter has an explicit gradient, so the CUDA kernels avoid autodiff overhead entirely.

Appendix B/C — Algorithms and Rasterizer Notes

  • Algorithm 1 (optimization + densification): diagrammed in Figure 3.
  • Algorithm 2 (GPU rasterization): diagrammed in Figure 4. Sorting uses 64-bit keys (low 32 = depth, high = tile index sized to resolution); tile ranges found by one thread per key comparing neighbors — eliminating Pulsar’s sequential primitive processing.
  • Numerical stability (Appendix C): skip \(\alpha < 1/255\), clamp \(\alpha \le 0.99\), stop blending before accumulated opacity exceeds 0.9999.

Appendix D — Per-Scene Metrics

Tables 4–9 give per-scene SSIM/PSNR/LPIPS for all methods and real scenes. Over the full Mip-NeRF360 dataset, the authors’ own Mip-NeRF360 runs average PSNR 27.58, SSIM 0.790, LPIPS 0.240.

References (selected)

Full bibliography in the paper. Most relevant anchors:

  • Kerbl, Kopanas, Leimkühler, Drettakis. 3D Gaussian Splatting for Real-Time Radiance Field Rendering. ACM TOG 42(4), 2023. arXiv:2308.04079
  • Mildenhall et al. NeRF. ECCV 2020.
  • Barron et al. Mip-NeRF 360. CVPR 2022. (quality baseline)
  • Müller et al. Instant Neural Graphics Primitives (InstantNGP). ACM TOG 2022. (speed baseline)
  • Fridovich-Keil & Yu et al. Plenoxels. CVPR 2022. (neural-network-free baseline)
  • Lassner & Zollhöfer. Pulsar. CVPR 2021. (tile/sort renderer inspiration)
  • Zwicker et al. EWA Volume/Surface Splatting. 2001. (2D projection of Gaussians)
  • Kopanas et al. Point-Based Neural Rendering with Per-View Optimization. CGF 2021. (rasterizer lineage)
  • Merrill & Grimshaw. GPU radix sort. 2010.
  • Schönberger & Frahm. Structure-from-Motion Revisited (COLMAP). CVPR 2016. (input pipeline)