A voxel grid or a mesh stores a scene's geometry explicitly — every cell, every vertex, sitting in memory waiting to be read. What if a scene were instead stored as weights: a tiny function that, when you ask it "what's here, and what does it look like from this direction?", answers on demand?
A camera ray passes through three samples: a half-transparent red, a half-transparent green, then a fully opaque blue surface behind them. Drag the red sample's opacity. Push it toward 1 and it steals almost all the color for itself — nothing behind it can show through an opaque sample. Drop it toward 0 and green, then blue, get their turn.
A NeRF is a tiny MLP: feed it a 3D point and a viewing direction, it hands back a density (how "solid" that point is) and a color. Marching a ray through the scene takes samples along it, turns each one's density into an opacity via the step size between samples, and composites them exactly like alpha-blending layers in image editors — front-to-back:
- — the density the MLP predicts at sample ; — the step size (world-space gap) to the next sample.
- — sample 's own opacity: denser samples, or longer steps through them, block more light.
- — transmittance: the fraction of light that survives every nearer sample before reaching sample .
- — the RGB color the MLP predicts at sample .
- Sample 1 (red): alpha=0.5
Full transmittance so far (), so its contribution is — half the pixel is already claimed before any other sample is even considered.
- Sample 2 (green): alpha=0.5
Only of the pixel is left to compete for. Contribution .
- Sample 3 (blue, fully opaque): alpha=1
remains. Contribution . Total: — the ray terminated on something fully opaque, so every bit of the pixel got assigned.
Now drag density , not raw opacity — the actual quantity a NeRF's MLP predicts. Watch how quickly saturates toward 1: by the sample is already almost fully opaque, which is why NeRF densities are usually shown on a log-ish scale in papers.
Two more density values for sample 1 (step size , samples 2-3 unchanged):
- sigma = 2 (moderately dense)
. , so sample 3's final weight drops to — a dense first sample starves everything behind it.
- sigma = 0.1 (nearly transparent)
. , sample 3's weight becomes — almost the same as if sample 1 weren't there at all.
Drag sample 1's opacity until the far, fully-opaque sample (sample 3) receives ≈ 0.4 of the final color's weight.
A NeRF replaces explicit geometry with a tiny neural function queried millions of times per image — every pixel needs its own ray, and every ray needs dozens of MLP calls. That's exactly why it's slow: the next chapter keeps the idea (query a point, get back a feature) but replaces the "tiny MLP, queried a lot" with "tiny MLP, queried a lot less, backed by a fast lookup table."