Computer graphics
A renderer is a loop over pixels
Before engines, before GPUs — the idea is small enough to hold in your head.
Strip away the engine, the shaders and the GPU and a renderer is one question asked many times: for this pixel, which direction did light come from, and what did it hit? Answer it for every pixel and you have an image.
Two broad families answer it. In a simple teaching model, the choice between them is the first real decision:
Ray tracing — in a basic version, start at the camera and shoot one ray through each pixel to find the nearest hit; additional rays handle effects such as shadows and indirect light.
Rasterization — start at the triangles, project them onto the image, and generate fragments for the samples they cover.
Ray tracing makes visibility along a ray explicit, so shadow tests and specular reflection or transmission fit naturally into the same framework; each effect may still need extra rays and material models. Rasterization is designed to process many projected primitives efficiently. Modern engines combine both approaches, and neither makes the other obsolete.
// The whole of a first ray tracer, in pseudocode
for y in 0..height:
for x in 0..width:
ray = camera.rayThrough(x, y) // origin + direction
hit = scene.nearestHit(ray) // brute force is fine at first
color = hit ? shade(hit, ray) : background
image[y][x] = color
// shade() is where all the physics lives:
// normal, material, light directions, and later: recursion for reflectionThe camera part is worth doing by hand once. A ray through pixel (x, y) is:
// Map pixel -> normalised device coords in [-1, 1]; fov is vertical here
ndc_x = (2*(x + 0.5) / width - 1) * aspect * tan(fov/2)
ndc_y = (1 - 2*(y + 0.5) / height) * tan(fov/2)
// Direction in camera space, then rotate into world space
dir_camera = normalize(vec3(ndc_x, ndc_y, -1))
dir_world = cameraBasis * dir_camera
// The +0.5 matters: it samples the CENTRE of the pixel, not its corner.Once this loop works you have the skeleton that everything else hangs on. Shadows are "shoot a ray at the light". Reflections are "call shade() again along the reflected direction". Depth of field is "jitter the ray origin over a lens". Same loop, richer question.
What is the core operation of a ray tracer?
Why do BVH / kd-tree / grids exist?
Ray tracing
From camera, one ray per pixel; ask what it hits.
Rasterization
From triangles, project and fill the pixels they cover.
Nearest hit
The expensive inner loop; every acceleration structure targets it.
Review cards
Ray tracing
From camera, one ray per pixel; ask what it hits.
Rasterization
From triangles, project and fill the pixels they cover.
Nearest hit
The expensive inner loop; every acceleration structure targets it.
Sources for this lesson
Below are the references, editions and original links for further reading and checking.
BookComputer Graphics from Scratchfree
Gabriel Gambetta
No Starch Press, 2021
手写光追器 + 光栅化器,几乎不需要数学铺垫,最适合第一本。官网有全文。
Tomas Akenine-Möller, Eric Haines, Naty Hoffman
4th edition
实时渲染的参考手册。第 4 版新增 VR/AR 一章,并覆盖全局光照与曲线曲面。配套站点持续更新书目。
Lights up these nodes in the hub:b-01 · b-02