CodeRigor

FREE COURSE / REAL PRACTICE

Graphics & neural rendering

Connect geometry, cameras, scene representation and rendering through visual explanations and practical graphics projects.

Free lessons & exercises17 authored lessons4 units

What you’ll work toward

Build and inspect graphics components while keeping data layout, numerical behavior and interfaces explicit.

Read an explanation, inspect the diagrams and work through the available checks, debugging exercises and builds. Feedback and prerequisite links guide the next step.

Before you start

The entry lesson has no earlier CodeRigor skill prerequisite. Start there and follow the sequence.

Individual lessons can add prerequisites. The course map shows your actual readiness.

A look inside the first lesson

3D math for graphics: vectors and matrices

C++
#include <cmath>
#include <print>

struct vec3 { float x = 0, y = 0, z = 0; };

constexpr vec3 operator-(vec3 a, vec3 b) { return {a.x - b.x, a.y - b.y, a.z - b.z}; }
constexpr vec3 operator/(vec3 a, float s) { return {a.x / s, a.y / s, a.z / s}; }
constexpr float dot(vec3 a, vec3 b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
constexpr vec3 cross(vec3 a, vec3 b) {
    return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
}
inline vec3 normalize(vec3 a) {
    float len = std::sqrt(dot(a, a));
    return len > 0.0f ? a / len : vec3{};   // zero stays zero: no NaN
}

static_assert(cross({1, 0, 0}, {0, 1, 0}).z == 1.0f);   // right-handed

int main() {
    // Triangle normal: counter-clockwise vertices seen from the front.
    vec3 p0{0, 0, 0}, p1{1, 0, 0}, p2{0, 1, 0};
    vec3 n = normalize(cross(p1 - p0, p2 - p0));
    std::println("n = ({}, {}, {})", n.x, n.y, n.z);
    // A degenerate (zero-area) triangle:
    vec3 d = normalize(cross(p1 - p0, p1 - p0));
    std::println("degenerate = ({}, {}, {})", d.x, d.y, d.z);
}

Your course outline

Follow the lessons in curriculum order. Open a unit to preview the ideas you’ll work with.

UNIT 014 lessons Graphics: 3D math, cameras, rasterization
  1. LESSON 01.01

    3D math for graphics: vectors and matrices

    vec3 and mat4 the way renderers use them: dot and cross, points vs directions, homogeneous coordinates, column-major storage, TRS composition, rigid and general inverses, the normal matrix, and float precision.

    Open lesson
  2. LESSON 01.02

    Quaternions for rotation

    Unit quaternions as 3D Gaussian splatting uses them: Hamilton product, rotating vectors with q v q*, the half angle, the exact quaternion-to-matrix formula, double cover, slerp vs nlerp, and why not Euler angles.

    Open lesson
  3. LESSON 01.03

    Cameras and projection

    The pinhole camera end to end: world-to-camera extrinsics, intrinsics from a field of view, projecting points to pixels, one primary ray per pixel centre, OpenGL's projection matrix and NDC depth — and the OpenCV-vs-OpenGL axis conventions that break most radiance-field loaders.

    Open lesson
  4. LESSON 01.04

    Triangle rasterization

    Turn screen-space triangles into pixels the way GPUs do: edge functions, bounding boxes, the top-left fill rule, barycentrics, a z-buffer, perspective-correct interpolation and back-face culling.

    Open lesson
UNIT 024 lessons Graphics: rays, light, space
  1. LESSON 02.01

    Ray intersections: spheres, triangles, boxes

    Shoot rays at geometry the way a path tracer does: a numerically stable ray–sphere quadratic, Möller–Trumbore triangles with barycentrics, the slab test with IEEE infinities and its NaN trap, closest hit, and shadow acne.

    Open lesson
  2. LESSON 02.02

    Bounding volume hierarchies

    Make ray casting O(log n): a flattened 32-byte-node BVH built with the binned surface area heuristic, closest-first stack traversal with pruning, any-hit queries, refitting for animation, and how LBVH and RT hardware (BLAS/TLAS) fit in.

    Open lesson
  3. LESSON 02.03

    Shading and Monte Carlo light transport

    Radiance and the rendering equation, Lambert and GGX BRDFs, Monte Carlo estimators with cosine-weighted importance sampling, a branchless frame around the normal, Russian roulette, and lighting in linear space before the sRGB encode.

    Open lesson
  4. LESSON 02.04

    Morton codes and linear octrees

    Put 3D data in spatial order: quantise to a 21-bit grid, interleave bits into Morton codes with magic-number spreading, radix-sort, read a linear octree off the common prefixes, and answer cell and radius-neighbour queries — the ordering behind point-cloud and splat compression, LOD and k-NN.

    Open lesson
UNIT 036 lessons Graphics: neural rendering
  1. LESSON 03.01

    Volume rendering for NeRF

    Turn densities and colours along a ray into a pixel: the volume rendering integral and its alpha-compositing quadrature, transmittance, weights and depth, stratified and inverse-CDF hierarchical sampling, and NeRF's positional encoding.

    Open lesson
  2. LESSON 03.02

    Spherical harmonics for view-dependent colour

    Evaluate degree-3 real spherical harmonics exactly like 3D Gaussian Splatting — constants, signs, +0.5 and clamp — and project functions on the sphere onto them by Monte Carlo.

    Open lesson
  3. LESSON 03.03

    Multiresolution hash grid encoding

    Instant-NGP's input encoding: L grids of geometric resolution, coarse ones stored densely and fine ones through a spatial hash, trilinear lookups concatenated for a tiny MLP — and the scatter-add backward pass that trains the tables.

    Open lesson
  4. LESSON 03.04

    3D Gaussian Splatting: the rasterizer

    Render millions of anisotropic 3D Gaussians in real time: Σ = R S Sᵀ Rᵀ, EWA projection to a screen-space conic, 16×16 tile binning with one radix sort on (tile, depth) keys, and front-to-back alpha blending — the reference CUDA rasterizer, rebuilt on the CPU.

    Open lesson
  5. LESSON 03.05

    Differentiable rendering: the backward pass

    Derive, implement and verify the gradient of a splatting renderer: reverse-mode chain rule, the back-to-front backward of alpha compositing that rebuilds T from the final transmittance, gradients through the 0.99 clamp, central-difference gradient checks, Adam with bias correction and per-group learning rates, L1 + D-SSIM, and adaptive density control.

    Open lesson
  6. LESSON 03.06

    Compressing and streaming Gaussian splats

    Shrink a 3DGS scene from ~240 bytes to 16 bytes per splat: fp16 with correct rounding, Morton-sorted chunks with per-chunk quantisation, smallest-three quaternions, log scales, SH pruning and k-means codebooks — then measure the damage with PSNR and stream it coarse-to-fine.

    Open lesson
UNIT 043 lessons C++ ↔ Python and GPU
  1. LESSON 04.01

    C++ ↔ Python boundaries with pybind11

    Put the hot loop in C++ and keep the research in Python: pybind11 modules over NumPy arrays (buffer protocol, dtype and shape checks, strides), ownership across the boundary (return value policies, keep_alive, capsules, zero-copy views), releasing the GIL, exception translation, and building the extension with CMake.

    Open lesson
  2. LESSON 04.02

    GPU kernel basics (CUDA)

    The CUDA execution model from the kernel's point of view: grids, blocks and warps, index math and bounds checks, coalesced global memory, shared-memory tiles and bank conflicts, __syncthreads rules, atomics, streams and launch errors — graded on a deterministic CPU kernel simulator.

    Open lesson
  3. LESSON 04.03

    GPU correctness and honest benchmarks

    Check GPU results against a CPU reference with abs/rel/ULP tolerances, time kernels honestly (cudaEvent, warm-up, sync, transfers, medians), profile with Nsight, and write reports that never overclaim.

    Open lesson