TAI BUI
Back to curriculum
BuildPython

3D Vision — Point Clouds & NeRFs

3D vision comes in two flavours: point clouds, the sensor's raw output, and NeRFs, the learned volumetric field. Both are answering the same question: what is where in space.

TIME: ~45 minutesPREREQUISITES: Phase 4 Lesson 03 (CNNs), Phase 1 Lesson 12 (Tensor Operations)

Learning Objectives

  • Distinguish explicit (point cloud, mesh, voxel) and implicit (signed distance field, NeRF) 3D representations and when each is used
  • Understand PointNet's symmetric-function trick that makes a neural network permutation-invariant over an unordered set of points
  • Trace a NeRF forward pass: ray casting, volumetric rendering, positional encoding, MLP density+colour head
  • Use `nerfstudio` or `instant-ngp` for pretrained 3D reconstruction from a small set of posed images

The Problem

A camera gives you a 2D image. A LIDAR gives you a set of 3D points with no ordering at all. A structure-from-motion pipeline gives you a sparse cloud of 3D keypoints, and a NeRF reconstructs an entire scene from a handful of posed photos. Call all four of those "vision" and you'd be right, but none of them look anything like the dense grid a CNN expects.

That mismatch matters because almost every high-value robotics task runs in 3D: grasping, obstacle avoidance, navigation, AR occlusion, capturing real-world content. If you only know how to process 2D images, you're locked out of the fastest-growing part of the field: AR/VR content, robotics, autonomous driving stacks, NeRF-based reconstruction for real estate or construction.

Two representations dominate, and for different reasons. Point clouds are what sensors hand you for free. NeRFs, and everything downstream of them like 3D Gaussian splatting and neural SDFs, are what you get when you ask a neural network to learn the scene instead.

Warm-up0/3
1. You're counting how many ping-pong balls in a bag are orange. Does the order you pull them out of the bag change the final count?Warm-up
Seven ping-pong balls in a row, some orange and some gray, in the order they were pulled from a bag, next to a dashed box asking for the count of orange balls.
The balls in one pull order; the count itself is left for the reader to work out.
2. A self-driving car's LIDAR sensor and a CAD model of a chair are both '3D data,' but they come from very different sources. Which is the noisy, incomplete scan of the real world, and which is the clean, human-designed shape?Warm-up
Left, a car with a dashed sensor beam aimed at a chair, labelled a LIDAR sensor on a car scans it. Right, the same chair drawn inside a monitor, labelled a person draws it in CAD software. Below, a dashed box asking which one comes out noisy and incomplete.
The two sources the question names, with the chair drawn the same way on both sides.
3. Which of these waves repeats most often (oscillates fastest) as x increases?Warm-up
Two waves drawn over the same stretch of x, the upper one completing three repeats and the lower one completing six.
What it means for one wave to repeat more often than another over the same stretch of x.
Check: The Problem0/1
1. Why can a plain CNN not process a raw point cloud directly?Explain
A scatter of ten points on the left, a fixed 6 by 6 grid in the middle labelled CNN input, and a dashed question-mark box on the right.
A point cloud and a CNN's expected grid input, side by side.

The Concept

Explicit vs. implicit representations

Every 3D representation is either explicit or implicit. An explicit representation stores geometry directly: a point cloud is a literal list of 3D points, a mesh is a set of vertices connected into triangular faces, and a voxel grid is a 3D array of cells marking occupied space. Query any of them and you get back exactly what was stored, nothing more. An implicit representation stores a function instead: a signed distance field (SDF) returns the distance from any query point to the nearest surface, and a NeRF returns a density and colour for any query point and viewing direction. You don't read geometry off an implicit representation, you query it.

The trade-off is memory against resolution. A point cloud or voxel grid is bounded by however many points or cells got stored, so more detail costs more memory, and any gap between samples is just a gap. A function has no such ceiling: an SDF or a NeRF MLP can be queried at any resolution, including one finer than anything it trained on, because the function is continuous rather than a fixed set of samples. That continuity is also why implicit representations are slower to read from. Rendering a pixel means running a network, not indexing an array.

Meshes and voxel grids matter mostly for context here. The rest of this lesson works the two ends readers hit most often in practice: point clouds, what a sensor hands you directly, and NeRFs, what a network learns to fill in when you only have photos.

Point clouds

A point cloud is an unordered set of N points in R^3, optionally each with features (colour, intensity, normal).

cloud = [
  (x1, y1, z1, r1, g1, b1),
  (x2, y2, z2, r2, g2, b2),
  ...
  (xN, yN, zN, rN, gN, bN),
]

No grid, no connectivity. Two properties make this hard for neural networks:

  • Permutation invariance: the output must not depend on point order.
  • Variable N: a single model must handle clouds of different sizes.

PointNet (Qi et al., 2017) solved both with one idea: apply a shared MLP to every point, then aggregate with a symmetric function (max pool). The result is a fixed-size vector that does not depend on order.

f(P) = max_{p in P} MLP(p)

This is the entire core of PointNet. Deeper variants (PointNet++, Point Transformer) add hierarchical sampling and local aggregation, but the symmetric-function trick never changes.

The PointNet architecture

Mermaid diagram

"Shared MLP" means the same MLP runs on every point independently, implemented in practice as a 1x1 conv over the point dimension for speed.

Neural Radiance Fields (NeRFs)

A NeRF is a neural network that stores a 3D scene as a function: it maps a 3D position and viewing direction, (x, y, z, viewing_direction), to a density and a colour, (density, colour). Mildenhall et al. (2020) built it to answer one question: can you reconstruct a 3D scene from a handful of photos? Rendering a new view means running a ray-casting loop over that function.

NeRF MLP:  (x, y, z, theta, phi) -> (sigma, r, g, b)

To render a pixel (u, v) of a new view:
  1. Cast a ray from the camera through pixel (u, v)
  2. Sample points along the ray at distances t_1, t_2, ..., t_N
  3. Query the MLP at each point
  4. Composite the colours weighted by (1 - exp(-sigma * dt))
  5. The sum is the rendered pixel colour

A loss compares the rendered pixel to the ground-truth pixel in the training photos. Backprop through the rendering step updates the MLP. No 3D ground truth, no explicit geometry: the scene lives in the MLP's weights.

Positional encoding in NeRF

Positional encoding maps each coordinate into a Fourier feature vector, sine and cosine at multiple frequencies, before it ever reaches the MLP:

gamma(p) = (sin(2^0 pi p), cos(2^0 pi p), sin(2^1 pi p), cos(2^1 pi p), ...)

NeRF needs this because a plain MLP fed raw (x, y, z) values can't represent high-frequency detail: MLPs are spectrally biased toward low frequencies, so without the encoding, renders come out blurry. NeRF uses up to L=10 frequency levels. Transformers use the same trick for positions, and it shows up again in diffusion time conditioning (Lesson 10).

Volumetric rendering

C(r) = sum_i T_i * (1 - exp(-sigma_i * delta_i)) * c_i

T_i  = exp(- sum_{j<i} sigma_j * delta_j)
delta_i = t_{i+1} - t_i

T_i is transmittance: how much light survives to reach point i. (1 - exp(-sigma_i * delta_i)) is the opacity at point i, and c_i is its colour. The final pixel is a weighted sum along the ray.

What replaced NeRFs

Pure NeRFs are slow to train (hours) and slow to render (seconds per image). The lineage since:

  • Instant-NGP (2022): hash-grid encoding replaces the MLP's position input; trains in seconds.
  • Mip-NeRF 360: handles unbounded scenes and anti-aliasing.
  • 3D Gaussian Splatting (2023): replaces the volumetric field with millions of 3D Gaussians; trains in minutes, renders in real time. The current production default.

Almost every NeRF product shipping in 2026 is actually 3D Gaussian splatting under the hood. The mental model is still NeRF.

Datasets and benchmarks

  • ShapeNet: classification and segmentation of 3D CAD models as point clouds.
  • ScanNet: real indoor scans for segmentation.
  • KITTI: outdoor LIDAR point clouds for autonomous driving.
  • NeRF Synthetic / Blended MVS: posed-image datasets for view synthesis.
  • Mip-NeRF 360 dataset: unbounded real scenes.
Check: The Concept0/21
1. What is a point cloud?Define
A scatter of nine dots, two of them labelled with coordinate tuples (x1,y1,z1) and (x2,y2,z2), next to the lesson's listing of a cloud as rows of x, y, z and r, g, b values.
Nine measured points, and the lesson's own listing of what one row holds.
2. What is PointNet?Define
A scatter of points labelled one point cloud, an arrow into a box labelled PointNet, and an arrow into a box labelled class scores, one per category.
What PointNet is handed and what it returns, without its internals.
3. What is a NeRF?Define
A box holding (x, y, z, theta, phi), an arrow into a box labelled NeRF MLP, and an arrow into a box holding (sigma, r, g, b).
The MLP line as the lesson writes it, symbols only.
4. What does positional encoding do in a NeRF?Define
A box holding one coordinate p, an arrow into the formula gamma(p) equals sin and cos of p at multiples of pi and increasing powers of 2.
The gamma(p) line quoted from the lesson, applied to a single coordinate.
5. What is volumetric rendering in a NeRF?Define
The formula C(r) equals the sum over i of T_i times one minus exp of minus sigma_i times delta_i, times c_i, above a line of six sample dots labelled t_1 through t_6, with notes naming sigma_i, c_i and delta_i.
The lesson's C(r) line and the samples its sum runs over.
6. What is Instant-NGP?Define
A box holding a coordinate x, y, z, an arrow into a box labelled hash-grid encoding, and an arrow into a box labelled small MLP.
The path a coordinate takes before the network sees it.
7. What is 3D Gaussian splatting?Define
A dense cluster of overlapping translucent ellipses, one of them outlined, with an arrow into a box labelled rendered view.
One scene drawn as a pile of overlapping translucent shapes.
8. What is a signed distance field (SDF)?Define
A circle standing for a surface, with a query point marked outside it and a dashed line labelled distance running from the point to the nearest spot on the circle.
One query point and the dashed line from it to the surface.
9. What separates explicit from implicit 3D representations, and which pairing is correct?Explain
Five boxes, point cloud, mesh, voxel grid, SDF and NeRF, above two empty dashed bins, one labelled explicit and one labelled implicit, both marked with a question mark.
Five representations and two empty category bins, not yet sorted.
10. Why can an SDF or a NeRF be queried at a finer resolution than anything it trained on, when a voxel grid cannot?Explain
A coarse fixed grid of cells on the left, labelled voxel grid, and a smooth curve with dots along it on the right, labelled SDF / NeRF.
A fixed grid of cells, next to the curve an SDF or NeRF stands for.
11. Why does PointNet aggregate per-point features with a max pool?Explain
Four point boxes, each feeding its own per-point feature box f1 through f4, with arrows converging on a dashed box marked question mark, aggregation.
Four per-point features about to be aggregated; the aggregation itself is not shown.
12. What does 'shared MLP' mean in PointNet?Explain
Three point boxes, each with an arrow into one single MLP box, and separate arrows out of it to three output boxes, out 1 through out 3.
Three points and one MLP box, each point getting its own output.
13. How can a NeRF be trained from ordinary photos with no 3D ground truth?Explain
A box reading posed photos, the only data, and a box reading 3D ground truth, none available, both feeding a NeRF MLP box, with a dashed box after it asking what the training signal is.
What the NeRF has and has not got, with the training signal left unresolved.
14. A NeRF MLP fed raw (x, y, z) coordinates produces blurry renders. What fixes this, and why?Explain
A box holding raw coordinates x, y, z, an arrow into an MLP box, and an arrow into a blurred, smudged square labelled rendered output.
Raw coordinates fed straight into the MLP, producing a blurred render.
15. In C(r) = sum_i T_i * (1 - exp(-sigma_i * delta_i)) * c_i, what does T_i represent?Explain
The formula C(r) equals the sum over i of T_i times one minus exp of minus sigma_i times delta_i, times c_i, above a table naming sigma_i as density and delta_i as the gap to the next sample, with T_i left as a question mark.
The compositing formula, with T_i the one symbol left unnamed.
16. How is a NeRF's rendered pixel computed?Explain
A camera, an image plane drawn as a grid of pixels with one cell highlighted and labelled pixel (u, v), a box reading the scene, the trained NeRF, and a dashed box asking how that pixel's colour is computed.
The view being rendered and the one pixel in question, with the method left unresolved.
17. A colleague replaces PointNet's max pool with concatenating per-point features in input order. The model's output now changes when the same cloud's points are shuffled. What was lost?Analyze
Two boxes, max pool labelled original PointNet and concatenate in order labelled colleague's version, above a one-row table recording that the colleague's output changes when the same cloud is shuffled, and a dashed box asking what property was lost.
The two aggregation steps, and the stem's own fact about the colleague's version.
18. A vendor's 'NeRF pipeline' trains in minutes and renders in real time. What is it most likely built on?Analyze
Two badges, training: minutes and rendering: real time, above a dashed box asking what the pipeline is built on.
The vendor's two claimed numbers, from the stem, with the underlying technology left unresolved.
19. In a rendered view, objects that sit behind a solid wall bleed into the wall's pixels. Which part of the compositing formula failed to suppress them?Analyze
A ray from a camera through a solid wall to a hidden object behind it, and a render patch showing colour bleeding through where the wall should block it, above a dashed box asking which part of the compositing formula failed.
The ray, the wall, the hidden object behind it, and the buggy render that lets it bleed through.
20. You run one cloud through a PointNet twice, once with its points shuffled. The outputs differ by about 1e-7. What is the right conclusion?Analyze
Two boxes, run A with points in order 1 and run B with the same points shuffled, above a badge reading difference about 1e-7.
Two runs of the same cloud in different orders, with the stem's own tiny output difference.
21. A robot must classify obstacles from raw LIDAR sweeps with varying point counts. Which design fits?Design
Two badges, sweep 1 with N points and sweep 2 with a different N, a note that the task is to classify the obstacle in each sweep, and a dashed box asking which architecture fits.
Two LIDAR sweeps with different point counts and the classification task posed for them.

Build It

Step 1: PointNet classifier

Same shared-MLP-then-max-pool idea from the Concept section, written out as a full classifier:

python
import torch
import torch.nn as nn
 
class PointNet(nn.Module):
    def __init__(self, num_classes=10):
        super().__init__()
        self.mlp1 = nn.Sequential(
            nn.Conv1d(3, 64, 1),    nn.BatchNorm1d(64),   nn.ReLU(inplace=True),
            nn.Conv1d(64, 64, 1),   nn.BatchNorm1d(64),   nn.ReLU(inplace=True),
        )
        self.mlp2 = nn.Sequential(
            nn.Conv1d(64, 128, 1),  nn.BatchNorm1d(128),  nn.ReLU(inplace=True),
            nn.Conv1d(128, 1024, 1), nn.BatchNorm1d(1024), nn.ReLU(inplace=True),
        )
        self.head = nn.Sequential(
            nn.Linear(1024, 512),   nn.BatchNorm1d(512),  nn.ReLU(inplace=True),
            nn.Dropout(0.3),
            nn.Linear(512, 256),    nn.BatchNorm1d(256),  nn.ReLU(inplace=True),
            nn.Dropout(0.3),
            nn.Linear(256, num_classes),
        )
 
    def forward(self, x):
        # x: (N, 3, num_points) — transposed for Conv1d
        x = self.mlp1(x)
        x = self.mlp2(x)
        x = torch.max(x, dim=-1)[0]       # (N, 1024)
        return self.head(x)
 
pts = torch.randn(4, 3, 1024)
net = PointNet(num_classes=10)
print(f"output: {net(pts).shape}")
print(f"params: {sum(p.numel() for p in net.parameters()):,}")

About 1.6M parameters. Runs on 1,024 points per cloud.

Step 2: Positional encoding

The Fourier-feature transform from the Concept section, as actual code:

python
def positional_encoding(x, L=10):
    """
    x: (..., D) -> (..., D * 2 * L)
    """
    freqs = 2.0 ** torch.arange(L, dtype=x.dtype, device=x.device)
    args = x.unsqueeze(-1) * freqs * 3.141592653589793
    sinc = torch.cat([args.sin(), args.cos()], dim=-1)
    return sinc.reshape(*x.shape[:-1], -1)
 
x = torch.randn(5, 3)
y = positional_encoding(x, L=10)
print(f"input:  {x.shape}")
print(f"encoded: {y.shape}     # (5, 60)")

Multiplying by 2^l * pi gives progressively higher frequencies.

Step 3: Tiny NeRF MLP

Positional encoding feeding straight into the density-and-colour MLP described above:

python
class TinyNeRF(nn.Module):
    def __init__(self, L_pos=10, L_dir=4, hidden=128):
        super().__init__()
        self.L_pos = L_pos
        self.L_dir = L_dir
        pos_dim = 3 * 2 * L_pos
        dir_dim = 3 * 2 * L_dir
        self.trunk = nn.Sequential(
            nn.Linear(pos_dim, hidden), nn.ReLU(inplace=True),
            nn.Linear(hidden, hidden),  nn.ReLU(inplace=True),
            nn.Linear(hidden, hidden),  nn.ReLU(inplace=True),
            nn.Linear(hidden, hidden),  nn.ReLU(inplace=True),
        )
        self.sigma = nn.Linear(hidden, 1)
        self.color = nn.Sequential(
            nn.Linear(hidden + dir_dim, hidden // 2), nn.ReLU(inplace=True),
            nn.Linear(hidden // 2, 3), nn.Sigmoid(),
        )
 
    def forward(self, x, d):
        x_enc = positional_encoding(x, self.L_pos)
        d_enc = positional_encoding(d, self.L_dir)
        h = self.trunk(x_enc)
        sigma = torch.relu(self.sigma(h)).squeeze(-1)
        rgb = self.color(torch.cat([h, d_enc], dim=-1))
        return sigma, rgb
 
nerf = TinyNeRF()
x = torch.randn(128, 3)
d = torch.randn(128, 3)
s, c = nerf(x, d)
print(f"sigma: {s.shape}   rgb: {c.shape}")

Tiny next to the original NeRF, which runs two MLP trunks eight layers deep, but it's enough to see the architecture clearly.

Step 4: Volumetric rendering along a ray

The compositing formula from the Volumetric rendering section, run over one ray:

python
def volumetric_render(sigma, rgb, t_vals):
    """
    sigma: (..., N_samples)
    rgb:   (..., N_samples, 3)
    t_vals: (N_samples,) distances along the ray
    """
    delta = torch.cat([t_vals[1:] - t_vals[:-1], torch.full_like(t_vals[:1], 1e10)])
    alpha = 1.0 - torch.exp(-sigma * delta)
    trans = torch.cumprod(torch.cat([torch.ones_like(alpha[..., :1]), 1.0 - alpha + 1e-10], dim=-1), dim=-1)[..., :-1]
    weights = alpha * trans
    rendered = (weights.unsqueeze(-1) * rgb).sum(dim=-2)
    depth = (weights * t_vals).sum(dim=-1)
    return rendered, depth, weights
 
 
N = 64
t_vals = torch.linspace(2.0, 6.0, N)
sigma = torch.rand(N) * 0.5
rgb = torch.rand(N, 3)
rendered, depth, weights = volumetric_render(sigma, rgb, t_vals)
print(f"rendered colour: {rendered.tolist()}")
print(f"depth:           {depth.item():.2f}")

One ray, 64 samples, composite to a single RGB pixel and a depth.

Check: Build It0/9
1. With pts = torch.randn(4, 3, 1024) and net = PointNet(num_classes=10), what is net(pts).shape?Apply
A chain of five boxes, input, mlp1, mlp2, max pool and head, with shapes (4,3,1024), (4,64,1024) and (4,1024,1024) for the first three, and question marks for the max pool and head outputs.
PointNet's shapes for this call as far as mlp2, with the last two stages left blank.
2. The PointNet in Step 1 is fed clouds of 2048 points instead of 1024, batch size still 4. What happens?Apply
Three lines of code: pts of shape (4, 3, 2048) where Step 1 used 1024, the same PointNet(num_classes=10), and out = net(pts), above a dashed box asking what happens.
The one thing the stem changes, with the result left unresolved.
3. With x = torch.randn(5, 3) and the default L=10, what shape does positional_encoding(x) return?Apply
The lesson's positional_encoding function in full, followed by the two call lines x = torch.randn(5, 3) and y = positional_encoding(x, L=10), above a dashed box asking for y.shape.
The function's own code and the call the question makes, with the result left blank.
4. With nerf = TinyNeRF() and x, d both of shape (128, 3), what shapes do sigma and rgb have in the lesson's Step 3 example?Apply
Boxes for x and d, both shape (128, 3), both feeding one box labelled TinyNeRF forward, and two dashed boxes after it asking for sigma.shape and rgb.shape.
TinyNeRF's two inputs and its two outputs, with both output shapes left blank.
5. With the default TinyNeRF arguments, what is the input size of the first Linear layer inside self.color?Apply
The lesson's TinyNeRF constructor, showing its default arguments, the dir_dim line and the self.color Sequential, above a dashed box asking for the first Linear layer's in_features.
The constructor as the lesson writes it, with the layer's input size left blank.
6. In TinyNeRF, you change only the viewing direction d for a fixed position x. Which output can change?Apply
The TinyNeRF forward method, seven lines, exactly as the lesson's Step 3 writes it.
TinyNeRF's forward pass, with no line singled out.
7. In Step 4, t_vals = torch.linspace(2.0, 6.0, 64). What are the delta values volumetric_render computes?Apply
Three boxes showing t_vals[0] at 2.000, an ellipsis marked 64 samples, and t_vals[63] at 6.000, above a dashed box asking what delta volumetric_render computes from t_vals.
The first and last of the 64 sample positions, with the gaps left unresolved.
8. In volumetric_render, every entry of sigma is 0. What is the rendered colour?Apply
A note that sigma holds 0 for all 64 samples, above a dashed box asking what the rendered colour is.
The stem's condition, sigma zero everywhere along the ray, with the rendered colour left unresolved.
9. For the first sample along a ray, what is the transmittance T_1?Apply
The lesson's line for T_i, exp of minus the sum over j less than i of sigma_j times delta_j, above a dashed box asking for T_1.
The lesson's T_i line, with its value at the first sample left unresolved.

Use It

For real work:

  • nerfstudio (Tancik et al.): the current reference library for NeRF / Instant-NGP / Gaussian Splatting, with a command-line workflow plus a web viewer.
  • pytorch3d (Meta): differentiable rendering, point-cloud utilities, mesh ops.
  • open3d: point cloud processing, registration, visualisation.

For deployment, 3D Gaussian splatting has largely replaced pure NeRFs: it renders about 100x faster, and the reconstruction quality holds up just as well.

Check: Use It0/3
1. Why has 3D Gaussian splatting largely replaced pure NeRFs for deployment?Explain
Two boxes side by side, pure NeRF and 3D Gaussian splatting, above a dashed box asking why one replaced the other for deployment.
The two approaches the question compares, with no claim about either.
2. A client wants customers to walk through a listing captured with phone photos, with real-time rendering in a browser viewer. Which approach fits?Design
A box of several phone photos, an arrow into a dashed reconstruction box, and an arrow into a box labelled browser, real time.
The client's phone photos and the real-time browser requirement, with the reconstruction method left unresolved.
3. You have 20 posed photos of a small object and want a usable 3D reconstruction without writing your own training loop. Which tool fits, and why?Design
A box reading 20 posed photos of a small object, an arrow into a dashed tool box, and an arrow into a box labelled 3D reconstruction.
The 20 posed photos and the reconstruction goal, with the tool left unresolved.

Ship It

This lesson produces:

  • outputs/prompt-3d-task-router.md, a prompt that routes to the right 3D representation (point cloud, mesh, voxel, NeRF, Gaussian splat) based on task and input data.
  • outputs/skill-point-cloud-loader.md, a skill that writes a PyTorch Dataset for .ply / .pcd / .xyz files with correct normalisation, centring, and point sampling.
Author's Note

I've lost count of how many times someone has pitched me a "NeRF pipeline" that turned out to be 3D Gaussian splatting wearing an old name. Same rendering idea in spirit, a completely different data structure underneath: minutes of training instead of hours, real-time rendering instead of seconds per frame. If you only know the marketing term, you can't tell a real reconstruction pipeline from a photogrammetry mesh with new branding stapled on.

Once you know the ray integral and the density field cold, you can ask two or three sharp questions and know within minutes which one you're actually looking at. That's worth more than knowing any single library's API, and it's why this lesson spends more time on the math than on nerfstudio flags.

Exercises

  1. (Easy) Show that PointNet is permutation-invariant: run the same cloud through twice, once with points shuffled. Verify outputs are identical up to floating-point noise.
  2. (Medium) Implement a minimal ray-generation function that, given camera intrinsics and pose, produces ray origins and directions for every pixel of an H x W image.
  3. (Hard) Train a TinyNeRF on a synthetic dataset of rendered views of a coloured cube (generated via differentiable rendering or a simple ray tracer). Report rendering loss at epoch 1, 10, and 100. At what epoch does the model produce recognisable views?

Key Terms

TermWhat people sayWhat it actually means
Point cloud"3D points from LIDAR"Unordered set of (x, y, z) + optional features per point
PointNet"First neural net on point clouds"Shared MLP per point + symmetric (max) pool; permutation-invariant by construction
NeRF"MLP that is the scene"Network mapping (x, y, z, dir) to (density, colour); rendered by ray casting
Positional encoding"Fourier features"Encode each coordinate into sin/cos at multiple frequencies to overcome MLP low-frequency bias
Volumetric rendering"Ray integration"Composite samples along a ray into a single pixel using transmittance and alpha
Instant-NGP"Hash-grid NeRF"Replaces NeRF's coordinate MLP with a multi-resolution hash grid; 100-1000x faster
3D Gaussian splatting"Millions of Gaussians"Scene = collection of 3D Gaussians; renders in real time, trains in minutes
SDF"Signed distance field"Function returning signed distance to the nearest surface; another implicit representation

Further Reading