Reading — step 1 of 5
Read
Triangle Rasterization with a Z-Buffer
You now have everything to draw a triangle: vertex positions in screen space, an edge function, barycentric coords, and a depth comparison. Time to fuse them.
Algorithm (per triangle):
1. Compute the screen-space bounding box of the triangle.
xmin = max(0, floor(min(v0.x, v1.x, v2.x)))
xmax = min(width-1, ceil(max(v0.x, v1.x, v2.x)))
ymin = max(0, floor(min(v0.y, v1.y, v2.y)))
ymax = min(height-1, ceil(max(v0.y, v1.y, v2.y)))
2. For each pixel (x, y) in [xmin..xmax] x [ymin..ymax]:
a. Compute barycentric (u, v, w) using the center of the pixel (x+0.5, y+0.5).
b. If any weight < 0: skip (outside triangle).
c. Interpolate depth: z = u * v0.z + v * v1.z + w * v2.z
d. If z < zbuffer[y][x]:
zbuffer[y][x] = z
color[y][x] = u * c0 + v * c1 + w * c2 (or any attribute)
Bounding box lets you skip entire empty regions — for a 1080p frame, the box of a 100-pixel triangle is 10000 pixels, not 2 million.
Pixel center sampling ((x+0.5, y+0.5)) avoids edges falling exactly on pixel boundaries and producing flickery results.
Incremental edge function: in a tight inner loop you can compute barycentric deltas once per row and per column rather than from scratch every pixel — that is the difference between a real-time rasterizer and a toy.
Top-left rule: when a triangle's edge runs exactly through a pixel center, exactly one of the two abutting triangles "owns" it. The standard tie-breaker is: a pixel belongs to the triangle on the top-left side of the shared edge. Without it, you get cracks or double-writes on shared edges.
GPU hardware does this for billions of triangles per second with parallel pixels, hierarchical Z, early-Z rejection, and quad-based shading. You do it for a few hundred to learn the mechanism.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…