Saral Shiksha Yojna
Courses/Computer Vision

Computer Vision

CSE471
Prof. Makarand Tapaswi + Prof. Charu SharmaSpring 2025-264 credits

NeRF & 3DGS — Per-Scene Optimisation and Differentiable Rendering

NotesStoryCaveman
Unit 9 — NeRF & 3D Gaussian Splatting

Many picture in, brand-new picture out

Ugg take 100 picture of cave-room with phone-rock, all sides. Now Ugg want computer show the room from a spot where Ugg never stood. That is novel view synthesis — make picture from new eye-spot not in the pile.

Hard for long time. Then 2020 bring NeRF (Neural Radiance Field): a tiny brain-net — give it a point and a look-direction, it grunt back colour and thickness. To paint one pixel, shoot spear-ray from eye through pixel, poke many points on ray, ask brain-net each, add colour weighted by thickness (volumetric rendering). Pretty, but SLOW: hours to train, paint only ~1 picture per second. No good for VR goggle.

Then 2023 bring 3D Gaussian Splatting (3DGS): same goal, fit picture to scene — but throw brain-net away, use millions of fuzzy blobs, paint real-time.

Two kind of scene-rock, plus fuzzy third

  • Explicit — count shape straight: point cloud, mesh (corners+faces), voxel grid.
  • Implicit — hide shape in a function. Signed Distance Function (SDF) grunt distance to nearest skin (skin = where it zero). NeRF also implicit.
  • 3DGS = new sixth slot: explicit like points, but each point a FUZZY blob (Gaussian), not hard dot.

3DGS no learn — it just fit one cave

Big idea: 3DGS have NO brain-net, NO learning. It is per-scene optimisation. Brain-net weights train on big pile so they work on NEW picture — generalise. 3DGS params fit ONE cave's picture; work nowhere else. New cave → whole new blobs. Ugg warn: no say 3DGS "learn weights that work everywhere" — WRONG.

COLMAP tell where Ugg stood

Before 3DGS, run picture through COLMAP — old Structure-from-Motion machine. It grunt back: (1) camera poses — 6-DOF spot+tilt of each picture; (2) sparse point cloud — few 3D dots from matched footprints. Poses say where picture taken; sparse cloud seed one blob per dot. Ugg warn: 3DGS NOT end-to-end — pose-finding done by old COLMAP first, before 3DGS begin!

Three big rocks hold the cave

Three Pillars:(1) Scene modelling — what each blob is.(2) Image formation — how blob make flat picture.(3) Optimisation — how blob fit picture.

Pillar one — what one fuzzy egg is

Each blob a fuzzy 3D egg, solid middle, see-through edge:

Front number DROPPED — opacity control the magnitude instead. Four groups:

  • **Mean ** — where egg sit. 3 number.
  • **Covariance — egg shape+tilt. 3×3 symmetric = 6 free number, but MUST be positive semi-definite (PSD)** or egg flip inside-out; raw SGD break it. Fix — split it: , PSD by build. = scale, 3 number, stored (always positive); = rotation as a quaternion, 4 number. Total 7. Quaternion not Euler because Euler get gimbal lock and jumps.
  • **Opacity ** — 1 number, sigmoid into . 1 solid, 0 ghost.
  • Colour by spherical harmonics — skin shine different per side (chrome ball white here, blue there); plain RGB no catch it. Use spherical harmonics (SH), wavy basis on the ball of look-directions. Degree 3: per colour ×3 colour = 48.

Add up: number per egg. Cave use 1M–4M eggs → 60M–240M number, still paint real-time.

Pillar two — squish eggs onto flat rock

Three step: (1) Sort by depth front-to-back. (2) Project each 3D egg to 2D — mean by pinhole, squished by the Jacobian of the projection. (3) Alpha-composite front-to-back. Ugg warn: no skip the sort — wrong order make wrong transmittance and wrong colour!

Rendering equation, memorise:

= egg colour (from SH at look-direction). = effective opacity — stored times flat-egg brightness at pixel (middle strong, edge weak). = transmittance — chance light slip past all front eggs unbeaten. Drop under → stop.

All step differentiable: 3DGS built a differentiable tile rasteriser in CUDA on GPU, so pixel-gradient flow back to every . THIS let gradient-descent work.

Pillar three — grow eggs, kill eggs

COLMAP give thousands; cave need millions. Adaptive Density Control (ADC), every few hundred step, three move: (1) Clone small egg in under-built spot (big position-gradient = one egg not enough) — copy it, let gradient pull copies apart. (2) Split big egg in over-built spot into two smaller (scale ) inside old egg. (3) Prune ghost eggs () — cost work, give nothing.

Loss:

= pixel-by-pixel difference (sharp); use SSIM for local brightness+contrast+structure. Full hunt: init from COLMAP → pick random picture → rasterise → loss → backprop → Adam step → sometimes ADC → repeat ~30,000 times.

Ugg count how good

Hold out every 8th picture to test. PSNR , for 8-bit; higher better, NO ceiling (Ugg warn: PSNR not bounded!), ~30 dB good. SSIM in , higher better, local structure. LPIPS — cut into patches, run through old pretrained net (AlexNet/VGG), measure deep-feature distance; lower better, match human eye. Arrows to memorise: PSNR ↑, SSIM ↑, LPIPS ↓. Test-grounds: Tanks & Temples, Deep Blending, Mip-NeRF 360, DL3DV-10K.

3DGS beat NeRF how

NeRF: implicit MLP, has brain-net, train hours–days, ~1 fps, hard to edit, small store ~MB. 3DGS: explicit eggs, no brain-net, train tens of minutes, >100 fps, easy edit one egg, big store ~GB. Trade: 3DGS pay memory, buy fast render+train and editability.

Ugg remember

  • 3DGS = per-scene optimisation, NO brain-net; the params ARE the eggs, they no generalise across caves.
  • Each egg = 59 numbers: . Never 58, never raw 6-number .
  • Render = sort by depth → project 3D→2D → alpha-composite; ; whole thing differentiable in CUDA.
  • ADC: clone small, split big (scale/1.6), prune ghost. COLMAP runs first — 3DGS not end-to-end.
  • Metrics PSNR↑ SSIM↑ LPIPS↓ (PSNR unbounded); quaternion is 4 number (Euler is 3 but has gimbal lock).
End of storyUnit 9 — NeRF & 3D Gaussian Splatting · NeRF & 3DGS — Per-Scene Optimisation and Differentiable Rendering