Neural Radiance Fields
Imagine photographing a coffee mug from twenty angles. You want a photorealistic image from an angle you never captured. Classical 3D Vision and Point Clouds pipelines solve this by reconstructing an explicit mesh or point cloud, then rasterizing it. This process struggles with thin structures, translucency, and view-dependent effects like glossy highlights. Neural Radiance Fields, introduced in 2020, replace the explicit geometry with a continuous function. This function is a small neural network. It maps any 3D point and viewing direction to a color and density. Rendering becomes a matter of querying this function along camera rays. The results are then integrated, exactly as physical light transport would. This idea matters because it collapses two traditionally separate stages. Reconstruction and rendering merge into one differentiable pipeline. It trains directly from posed photographs. There are no depth sensors, no meshes, and no explicit correspondence search. The scene representation is implicit. A multilayer perceptron's weights encode the entire volumetric radiance field of a scene. This often takes just a few megabytes. Yet it reproduces parallax, occlusion, and specular reflections with striking fidelity. This made NeRF the seed of an entire subfield of neural rendering. It spawned fast variants, generative extensions, and large-scale city reconstructions. The big picture: NeRF treats a static scene as a 5D function
mapping position and viewing direction to color and volume density. This function is trained so that rendering it via classical volume rendering matches a sparse set of ground-truth photographs. Gradients flow from a photometric loss. They pass through a differentiable renderer, back into the network weights. No 3D supervision is ever needed. This article develops the volumetric rendering equation and its discretization. It walks through the training and inference pipeline with full pseudocode. It analyzes the complexity and the correctness of the quadrature approximation. It traces a worked numerical example along a single ray. Finally, it surveys the pitfalls, history, and downstream impact of the idea. This is the idea that reframed 3D reconstruction as a regression problem.
- NeRF represents a scene as a continuous function from (position, view direction) to (color, density), stored in a neural network's weights.
- Images are synthesized by volume rendering: integrating color and density along camera rays through the network.
- Training uses only 2D posed photographs and a photometric loss — differentiable rendering supplies the 3D supervision signal.
- Positional encoding (Fourier features) is essential; without it MLPs cannot represent high-frequency scene detail.
- Hierarchical (coarse-to-fine) sampling concentrates compute where scene surfaces actually are, improving efficiency.
- The core weakness — slow per-scene optimization and per-pixel ray marching — motivated a wave of fast successors (voxel grids, hash encodings, Gaussian splatting).
A scene can be a neural network: query any point and direction, get color and density, and integrate along rays to render — training this network from photographs alone.
The idea
A radiance field is a function that assigns, to every point in space and every outgoing direction, the amount of light emitted or reflected toward that direction. Classical computer graphics represents such fields implicitly via surfaces plus a bidirectional reflectance model; Neural Radiance Fields instead represent the field directly as a continuous, learned function , parameterized by a neural network with weights . The network takes a 3D position and a viewing direction (or a unit vector) and outputs an emitted RGB color and a volume density , a scalar describing how opaque space is at that point, independent of viewing direction. Density depending only on position (not direction) encodes the physical fact that occupancy of space is not observer-dependent, while color depending on direction captures view-dependent effects such as specular highlights. Rendering a pixel means casting a ray from the camera center through the pixel, and computing the expected color received along that ray via the classical volume rendering integral:
Here is the accumulated transmittance, the probability that a photon travels from (near bound) to unobstructed. Intuitively, each infinitesimal segment of the ray absorbs and emits light in proportion to its density, and discounts contributions from points that are occluded by denser material closer to the camera. This is exactly the emission-absorption model used in medical volume rendering and physically-based smoke rendering, adapted here so that the entire field is a differentiable neural network rather than a voxel grid measured by a scanner. The key insight that made this practical is that the rendering integral is differentiable end-to-end with respect to : if predicted pixel colors are compared to ground-truth photograph pixels with a squared-error loss, gradients can be backpropagated through the discretized integral into the MLP weights. No 3D ground truth, depth maps, or explicit correspondences are required — only a set of images with known camera poses (obtained beforehand via 3D Vision and Point Clouds techniques like structure-from-motion). Two engineering ingredients are essential to make a simple MLP actually work in this role: positional encoding, which lifts low-dimensional coordinates into a high-dimensional space of sinusoids so the network can represent high-frequency detail (a manifestation of the spectral bias of MLPs toward smooth functions), and hierarchical volume sampling, a coarse-to-fine importance sampling scheme that concentrates ray samples near surfaces instead of wasting them in empty space.
How it works
Step 1 — Ray generation. For each pixel in the target image, use the known camera intrinsics and pose to compute the ray origin and direction .
Step 2 — Positional encoding. Raw coordinates are mapped through a fixed, non-learned sinusoidal embedding before entering the MLP:
This is applied per coordinate of (typically ) and per coordinate of (typically ), turning a 3-vector into a -dimensional vector.
Step 3 — Network evaluation. An 8-layer MLP takes , with a skip connection re-injecting at a middle layer, and outputs a 256-dim feature plus density (density is made to depend only on position by branching it off before direction is introduced). The feature is concatenated with and passed through a small additional head to produce the view-dependent RGB color .
Step 4 — Stratified sampling and quadrature. The continuous integral is approximated by sampling points along each ray, drawn via stratified sampling (one uniform random sample per bin) so that the network sees a continuum of positions during training rather than a fixed discrete set — this is what lets the trained field be continuous rather than griddy. The integral is discretized as a Riemann-sum-like quadrature (derived below) using the interval lengths :
Step 5 — Hierarchical (coarse-to-fine) sampling. A "coarse" network is evaluated at uniformly stratified samples first; the resulting per-sample weights , normalized, form a piecewise-constant probability density along the ray. A second, denser set of samples is then drawn from this density (inverse-transform sampling) and combined with the coarse samples to evaluate a "fine" network — concentrating the finer, more expensive computation near surfaces (where is large) instead of empty space or fully-occluded regions.
Step 6 — Loss and optimization. Both the coarse and fine rendered pixel colors are compared to ground truth via squared error, summed over a random batch of rays per iteration, and backpropagated with Adam to update all network weights. No explicit geometric regularizer is required, though later variants add depth or distortion losses.
Step 7 — Novel-view synthesis (inference). Given a new camera pose, repeat steps 1–5 (using only the fine network, or both, averaged) for every pixel to synthesize the output image. ``` function RENDER_RAY(o, d, t_near, t_far, N_coarse, N_fine, MLP_coarse, MLP_fine):
# --- Coarse pass: uniform stratified sampling --- bins <- partition([t_near, t_far] into N_coarse equal bins) t_c <- [uniform_random_sample(bin) for bin in bins] # stratified samples sigma_c, color_c <- [], [] for t in t_c: x <- o + t * d gamma_x <- positional_encode(x, L=10) gamma_d <- positional_encode(d, L=4) sigma, feat <- MLP_coarse.density_head(gamma_x) c <- MLP_coarse.color_head(feat, gamma_d) sigma_c.append(sigma); color_c.append(c) C_coarse, weights <- VOLUME_RENDER(t_c, sigma_c, color_c)
# --- Importance resampling from coarse weights --- pdf <- normalize(weights) # piecewise-constant density along ray t_f <- inverse_transform_sample(pdf, N_fine) # new samples concentrated near surfaces t_all <- sort(t_c UNION t_f)
# --- Fine pass: dense evaluation --- sigma_f, color_f <- [], [] for t in t_all: x <- o + t * d gamma_x <- positional_encode(x, L=10) gamma_d <- positional_encode(d, L=4) sigma, feat <- MLP_fine.density_head(gamma_x) c <- MLP_fine.color_head(feat, gamma_d) sigma_f.append(sigma); color_f.append(c) C_fine, _ <- VOLUME_RENDER(t_all, sigma_f, color_f) return C_coarse, C_fine
function VOLUME_RENDER(t, sigma, color): N <- length(t) T <- 1.0 C <- (0, 0, 0) weights <- array of size N for i in 1..N: delta_i <- (i < N) ? t[i+1] - t[i] : 1e10 # last interval extends to infinity alpha_i <- 1 - exp(-sigma[i] delta_i) # opacity contributed by segment i w_i <- T alpha_i C <- C + w_i color[i] weights[i] <- w_i T <- T (1 - alpha_i) # update transmittance return C, weights
function TRAIN(images, poses, intrinsics, MLP_coarse, MLP_fine, iters): for step in 1..iters: batch <- sample_random_rays(images, poses, intrinsics, batch_size=4096) loss <- 0 for (o, d, C_gt) in batch: C_coarse, C_fine <- RENDER_RAY(o, d, t_near, t_far, N_coarse=64, N_fine=128, MLP_coarse, MLP_fine) loss <- loss + ||C_coarse - C_gt||^2 + ||C_fine - C_gt||^2 backpropagate(loss) Adam_step(MLP_coarse.params, MLP_fine.params) ```
Complexity & correctness
Why the quadrature is a correct approximation. The continuous transmittance is the solution of the linear ODE , — a first-order absorption law identical to the Beer–Lambert law in optics. Discretizing the ray into segments of density assumed piecewise constant equal to on segment , the exact transmittance across that segment is , and the exact expected radiance contributed by segment (accounting for emission along the segment and outgoing attenuation) is under the assumption that color is also constant across the segment. Summing these gives exactly the estimator used above — it is not a crude Euler approximation but the exact solution of the volume rendering equation under the piecewise-constant assumption, which becomes arbitrarily accurate as and by the mesh-refinement limit of Riemann sums. Stratified (jittered) sampling additionally makes an unbiased Monte Carlo estimator of the true integral in expectation over the random offsets, since each stratum contributes its own independent uniform sample rather than a fixed grid point — this is precisely why the network is trained on a continuum of positions rather than memorizing fixed depths.
Why hierarchical sampling helps without introducing bias. The fine samples are drawn from the empirical density induced by the coarse weights , which by construction is large exactly where the ray's coarse pass estimated substantial radiance contribution (i.e., near opaque surfaces) and near zero in free space or fully-occluded regions. This is textbook importance sampling: allocating more samples where the integrand is large reduces the variance of the finite-sample estimate for a fixed sample budget, without biasing the estimator, since the final compositing still uses the actual (position-dependent) evaluated at the resampled points, not the coarse network's stale predictions.
Why positional encoding is necessary, not cosmetic. A neural tangent kernel argument explains the effect: standard MLPs with smooth activations have kernels that decay rapidly at high frequencies, exhibiting a strong spectral bias that makes them converge slowly on and often fail to represent fine spatial detail (sharp edges, thin structures) when the raw low-dimensional coordinate is the input. Composing the input with fixed sinusoids of exponentially increasing frequency reshapes the effective kernel to have significant support at high frequencies, letting the same MLP architecture fit high-frequency signals — an empirically and theoretically documented effect, not a heuristic add-on.
Time complexity. Let be rays per training batch, samples per ray, and the cost of one MLP forward/backward pass. One training iteration costs — every sample along every ray requires an independent network evaluation, since the field has no shared spatial structure to exploit (this is the classic implicit-representation tradeoff: compactness of parameters versus cost of querying). With , , and a modest 8-layer, 256-wide MLP, a single scene commonly requires – iterations, translating to one to two GPU-days on a single high-end GPU in the original formulation. Rendering one novel view costs — proportional to total pixels times samples times per-query cost, with no reuse across pixels, which is the main practical bottleneck addressed by later accelerated variants.
Space complexity. The learned representation itself is remarkably compact: where is the MLP parameter count, typically a few megabytes, independent of scene resolution or extent — a sharp contrast to explicit voxel grids or point clouds whose memory scales with or . This compactness is a direct benefit of the implicit-function representation, at the cost of the query-time expense above.
Honest tradeoffs. NeRF assumes a static scene with fixed lighting and accurately known camera poses; it has no native mechanism for dynamic content, relighting, or pose uncertainty (all addressed by later extensions). Per-scene optimization means a trained NeRF does not generalize to new scenes without retraining, unlike a feed-forward image-to-image network. The reliance on volumetric density rather than an explicit surface can create "floaters" (small suspended blobs of density) when views are sparse or inconsistent, since the optimization problem is under-constrained by too few rays.
Worked example
Consider a single ray passing near a red opaque sphere, sampled at five points along the ray with the network (hypothetically, post-training) producing the following outputs. Distances are in scene units; density in units of inverse length; colors are RGB in .
| (before segment) | |||||||
|---|---|---|---|---|---|---|---|
| 1 | 2.0 | 0.5 | 0.01 | 0.00499 | 1.0000 | 0.00499 | (0.1, 0.1, 0.9) |
| 2 | 2.5 | 0.5 | 0.02 | 0.00995 | 0.99501 | 0.00990 | (0.1, 0.1, 0.9) |
| 3 | 3.0 | 0.5 | 8.0 | 0.98168 | 0.98511 | 0.96676 | (0.9, 0.05, 0.05) |
| 4 | 3.5 | 0.5 | 7.5 | 0.97654 | 0.01807 | 0.01765 | (0.85, 0.05, 0.05) |
| 5 | 4.0 | 0.5 | 0.005 | 0.00250 | 0.00042 | 0.00000105 | (0.1, 0.1, 0.9) |
Step through the transmittance recursion explicitly:
- (nothing occludes the first segment).
- After segment 1: .
- After segment 2: .
- After segment 3 (this is where the sphere surface sits — density jumps to 8.0): (matches table to rounding).
- After segment 4: .
The rendered pixel color is the weighted sum:
The result is a nearly saturated red, exactly as expected: samples 3 and 4 (which straddle the sphere's surface, where density spikes) dominate the weighted sum because they carry almost all of the accumulated transmittance-times-opacity mass ( of the total), while the low-density background samples (blue sky, color (0.1,0.1,0.9)) contribute almost nothing — precisely because has already collapsed to near zero by the time the ray reaches them. This traces exactly why hierarchical sampling concentrates fine-pass samples around –: that is where peaks, and it is where additional samples reduce estimator variance the most.
Common pitfalls & traps
| Pitfall | Why it happens | Fix |
|---|---|---|
| Omitting positional encoding | Raw has spectral bias; renders come out blurry, missing fine texture | Always encode coordinates with sinusoids before the MLP (verify empirically the training loss curve fails to fit high-frequency views without it) |
| Inaccurate camera poses | NeRF is exquisitely sensitive to pose error; small pose noise causes systematic blur or ghosting | Run robust structure-from-motion first, or jointly optimize poses with the field (bundle-adjusting variants) |
| Too few / poorly distributed input views | Under-constrained density field creates "floaters," phantom geometry that hallucinates plausible-looking blobs | Add regularizers (depth priors, distortion loss) or increase view coverage, especially around thin/occluded structures |
| Confusing coarse and fine losses | Forgetting to backpropagate through both coarse and fine renders wastes the coarse network's guidance signal | Always sum losses on both outputs, since coarse weights directly shape fine-pass sampling |
| Using a fixed sample grid instead of stratified sampling | Network overfits to exact sampled depths, and cannot interpolate to nearby depths at test time | Randomize sample offsets within each bin every training step |
| Applying at test time without the near/far bounds matching training | Rays that exit the trained scene bounding volume return degenerate/undefined density | Fit or estimate tight per-scene near/far planes from the input point cloud or camera baseline |
| Assuming NeRF generalizes across scenes | Each NeRF is a per-scene optimization; a network trained on one scene has no meaning applied to another | Use conditional/generalizable NeRF variants (e.g., feature-conditioned encoders) if cross-scene generalization is required |
Pioneers & history
The volume rendering equation NeRF relies on predates deep learning by decades, originating in physically-based computer graphics for rendering smoke, clouds, and medical CT/MRI volumes. What NeRF contributed was recognizing that this classical, fully differentiable integral could serve as the renderer inside an end-to-end learned pipeline, with a coordinate-based MLP as the scene representation being differentiated through.
Origins · 1 minBen Mildenhall and how this was discovered
Where this matters
NeRF-style representations underpin modern novel-view synthesis products for real-estate walkthroughs, cultural-heritage digitization, and e-commerce product visualization, where a handful of photographs must become a fully explorable 3D asset. Robotics and autonomous-driving teams use radiance-field reconstructions of street scenes for simulation and sensor-data augmentation, since a trained field can render synthetic camera views from arbitrary novel trajectories for testing perception stacks. Visual effects and virtual production pipelines use accelerated NeRF variants to convert on-set footage into relightable, camera-path-free 3D scene proxies. The broader research trajectory — encoding a signal as the weights of a small network, queried continuously rather than stored on a grid — reappears throughout implicit neural representations for signed distance functions, textures, and even physical fields, and its differentiable-rendering recipe (render, compare to real pixels, backpropagate) is a direct conceptual ancestor of vision-conditioned generative systems and the fusion of 3D scene understanding with language, foreshadowing the broader convergence explored under Multimodal Models. It also builds directly on techniques from Image Generation Fundamentals (photometric losses, coordinate-based networks) and complements point-cloud-based geometry pipelines from 3D Vision and Point Clouds by supplying the missing photorealistic, view-dependent appearance model.
Ask the tutor: How does 3D Gaussian Splatting replace NeRF's implicit MLP with an explicit, rasterizable representation while keeping differentiable rendering?
Does NeRF require any 3D sensor data, like LiDAR or depth cameras?
No. The only required inputs are a set of 2D photographs of a static scene along with their camera poses (position, orientation, and intrinsics), typically recovered via structure-from-motion software run once as preprocessing. The entire 3D structure — geometry as encoded by volume density, and appearance as encoded by view-dependent color — is inferred purely by making the differentiable volume renderer's output match the observed pixels. This is the central appeal of the approach: 3D supervision emerges implicitly from the consistency of many 2D observations, rather than being provided directly, which is why researchers describe NeRF as turning 3D reconstruction into a photometric regression problem.
Why can't a single feed-forward network render arbitrary scenes without per-scene training?
The original NeRF formulation optimizes a fresh set of MLP weights for every individual scene — the weights themselves are the memorized radiance field, so a network trained on one kitchen has no meaningful output for a different kitchen. This is unlike typical vision networks that generalize across images, because NeRF's function domain is 3D coordinates specific to one calibrated scene coordinate frame. Generalizable variants exist that condition an MLP on image features extracted from a small number of reference views, enabling few-shot or even single-shot rendering of new scenes, trading some quality for the ability to skip the expensive per-scene optimization loop entirely.
How does NeRF handle occlusion correctly if it only sees 2D images?
Occlusion emerges automatically from the physics encoded in the volume rendering integral itself. The accumulated transmittance term decays as density accumulates along the ray, so points behind an opaque surface contribute negligibly to the final pixel color regardless of what color the network predicts there. During training, gradients naturally push the network toward placing high density at the true occluding surface, because that is the density configuration consistent with all training views simultaneously — an occluder in one view but not another forces the geometry to be consistent with the ray in the view where it is occluded.
Why does NeRF use two networks (coarse and fine) instead of one?
Using two passes implements an efficient importance-sampling scheme. The coarse network is evaluated at cheap, uniformly stratified samples to get a rough estimate of where along each ray the scene surface or opacity mass is concentrated. This estimate defines a probability density used to draw additional, denser samples exactly where they matter most for the fine network, rather than uniformly across empty space. This two-stage design lets a fixed total sample budget deliver dramatically better rendering fidelity than spending the same budget on uniform sampling alone, since most of a typical ray's length passes through unoccupied space.
What causes the long per-scene training times, and how have later methods addressed it?
Training is slow because every one of the millions of ray-sample queries per iteration requires a full forward and backward pass through an 8-layer MLP, and this must repeat for hundreds of thousands of iterations to converge, with no shared computation across nearby points in space. Later methods replace or augment the pure MLP with explicit, spatially indexed structures — sparse voxel grids, multiresolution hash tables, or small per-cell networks — so that most of the "memory" of the scene is stored directly and only a lightweight network interprets it, cutting training from roughly a GPU-day to seconds while preserving quality.
Is NeRF the same thing as a point cloud or a mesh?
No — NeRF is an implicit representation: nothing enumerable like vertices, faces, or 3D points is explicitly stored. Instead, the scene exists only as a continuous function realized by network weights, queried on demand at any coordinate. This contrasts with the explicit representations covered in 3D Vision and Point Clouds, which store discrete geometric primitives directly. NeRF's implicit form gives compactness and smoothness (density and color vary continuously) at the cost of needing repeated, relatively expensive network evaluations to extract any explicit geometry or to render an image, whereas explicit representations can be rasterized directly.
Can NeRF handle moving objects or changing lighting?
Not in its original static-scene formulation, which assumes fixed geometry and fixed illumination across all training photographs; moving subjects or changing light will violate the model's core assumption and typically appear as ghosting or blur artifacts. Dynamic extensions add a time-conditioned deformation field that warps a canonical static NeRF to match each timestep, while appearance-varying extensions add per-image latent codes to absorb lighting or exposure changes without corrupting the shared geometry, but these are extensions layered on top of, not part of, the base formulation described here.