FREE COURSE / REAL PRACTICE
Graphics & neural rendering
Connect geometry, cameras, scene representation and rendering through visual explanations and practical graphics projects.
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
#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.
Graphics: 3D math, cameras, rasterization
- 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 - 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 - 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 - 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
Graphics: rays, light, space
- 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 - 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 - 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 - 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
Graphics: neural rendering
- 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 - 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 - 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 - 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 - 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 - 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
C++ ↔ Python and GPU
- 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 - 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 - 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