A triangle is continuous; a screen is a grid of pixels. Rasterization asks, for every pixel, one question: are you inside? Pineda's answer is three edge functions — a signed cross-product per edge. A pixel is inside iff all three share one sign, and those same three numbers, normalized, are the barycentric weights. Down the center, data flows: the triangle goes in, the edge functions decide, covered pixels come out. The blue team builds and defends it; the red team tries to break it.
source J. Pineda, A Parallel Algorithm for Polygon Rasterization, SIGGRAPH '88, Computer Graphics 22(4), 17–20 — doi:10.1145/54852.378457. Rendered, not quoted.
For an edge from a to b the edge function at point p is the 2D cross product
E(p) = (bx−ax)(py−ay) − (by−ay)(px−ax)
It is + on one side of the line, − on the other, 0 on it. A triangle has three. p is inside iff all three carry the same sign — which works for either winding. Live at the probe pixel:
| edge | E(p) | sign |
|---|
The three edge functions divided by the triangle's area are the barycentric coordinates — the exact weights that interpolate colour, depth, texture, everything, across the face.
So rasterization and the-barycentric are one loop: decide coverage and the weights in the same three multiplies, evaluated per pixel. This is the inner loop of every GPU. Each sphere is the next one's premise.
The blue team's live check: re-run the inside-test over a grid, both windings, against an independent matrix-solve reference. If red drops the winding handling, this badge is where it shows.
The input is three vertices V0 V1 V2 on a pixel grid. That is all a rasterizer is handed. Its two derived quantities:
| quantity | meaning |
|---|---|
| 2·Area | edge(V0,V1,V2) — signed; >0 CCW, <0 CW |
| E0 E1 E2 | one edge function per opposite vertex |
Each pixel is sampled at its center. The sign pattern of (E0,E1,E2) at that center is the whole decision — that is what you feed the panel below.
Drag a vertex. Each covered pixel is coloured by its barycentric weights (V0 V1 V2).
Move any vertex — coverage and weights are computed from the three edge functions on the spot, never looked up.
What the machine produces, proven: coverage that matches an independent point-in-triangle test over the whole grid for both windings; barycentric weights that sum to 1 and reconstruct the point to 1e-9; the three sub-triangle areas that partition the whole; and a top-left rule under which two triangles sharing an edge cover each seam pixel exactly once — no double-draw, no gap.
The blue team's witness (left) confirms this live; the red team (right) tries to make it wrong.
Worse, floating-point edge evaluation is not exact: two triangles sharing an edge can each round the boundary the other way, opening cracks or overlaps. Real GPUs evaluate edges in fixed-point with a snapped sub-pixel grid precisely so the shared edge is bit-identical on both sides. The math here is exact by construction; silicon has to earn it.
"Inside means all three edge functions are positive." Cut. Only for a CCW triangle. The honest test is same sign (all ≥0 or all ≤0); demand strictly-positive and every clockwise triangle rasterizes to nothing — exactly the tamper in window 6.
"Rasterizing fills the triangle's area." Cut. It point-samples pixel centers and answers yes/no. That discretization is the source of aliasing, not a detail.
"The top-left rule is cosmetic." Kept, corrected. Without it a shared edge is drawn by both triangles (blend/z errors) or neither (a gap). It hands each seam pixel to exactly one — a working tie-break, not decoration.
The red team's move: drop the same-sign handling and require all three edge functions strictly positive. Clockwise triangles now cover nothing. The blue team's witness (window 7) is watching.
Force strictly-positive and a CW-wound triangle vanishes — the witness recomputes, disagrees with the reference, and turns red. Nothing is faked; the attack is real and it is caught.