The camera can only see a six-sided box — near, far, left, right, top, bottom. Everything else is thrown away before it is ever drawn. A point is visible iff its signed distance to all six inward-facing planes is non-negative; a bounding sphere is culled iff it lies entirely beyond one plane — its centre farther than −radius. Down the center, data flows: a point or sphere goes in, six half-space tests decide, the verdict comes out. The blue team builds and defends; the red team attacks and breaks.
source Clark, J. H., Hierarchical geometric models for visible-surface algorithms, Comm. ACM 19(10):547–554, 1976 — doi:10.1145/360349.360354 (AMBER: paywalled). Rendered, not quoted.
The frustum is an intersection of six half-spaces. Each plane carries an inward unit normal n and offset d; the signed distance to a point is sd = n·p + d. Inside iff every sd ≥ 0. One negative sd is enough to reject.
Live signed distances for the current point:
| plane | inward n | sd = n·p + d |
|---|
The six planes are not arbitrary: they are the faces of the clip volume of the-perspective-projection. After the projection matrix, the frustum test collapses to six trivial comparisons — −w ≤ x,y,z ≤ w.
The engine proves the equivalence live: the same point, classified by world-space planes and by its clip coordinates, agrees exactly. Culling is the first optimization of every renderer — seeing means not drawing what you cannot see. Each sphere is the next one's premise.
The blue team's live check: re-run the six-plane test over the known anchors — a point inside, a sphere fully outside, a sphere that pokes in, a point on the far boundary. If red flips a plane, this badge is where it shows.
Feed the machine a point p = (x, y, z) in view space — the camera at the origin looking down −z, near at z = −1, far at z = −4, a 90° field of view. Or feed a bounding sphere (that same centre, plus a radius r).
| plane | meaning | inward n | d |
|---|---|---|---|
| near | z ≤ −1 | (0, 0, −1) | −1 |
| far | z ≥ −4 | (0, 0, 1) | 4 |
| left | x ≥ z | (1, 0, −1)/√2 | 0 |
| right | x ≤ −z | (−1, 0, −1)/√2 | 0 |
Side planes pass through the apex (the eye), so their offset is 0; near and far are the flat caps. That is the whole input — a point (or sphere) and six fixed planes.
Top-down x–z slice. Wedge = frustum; green visible, red culled, current point ringed.
Every sd is computed from n·p + d on the spot, never looked up. Sliders move the point; the six tests re-decide instantly.
What the machine produces, proven: VISIBLE iff all six sd ≥ 0, else CULLED by the first failing plane. For a sphere: culled iff some sd(centre) < −r — a conservative test that never discards geometry that pokes inside. The current point's clip coordinates, from the projection matrix, agree with the plane verdict:
The blue team's witness (left) confirms these anchors live; the red team (right) tries to make a visible point read culled.
And it is only object-level: it cannot know that a wall in front hides the object behind it — that is occlusion, a different pass (z-buffer, Catmull 1974). Extracting the six planes from a combined view-projection matrix is also numerically fragile; a mis-normalized normal quietly corrupts the −radius comparison.
"Culling makes rendering faster by drawing fewer pixels." Cut. It skips whole objects before rasterization — it saves vertex and draw work, not per-pixel fill. Overdraw is the z-buffer's problem.
"If a sphere's centre is outside the frustum, cull it." Cut. A centre outside can still poke in. Compare the signed distance to −radius, never to 0 — the engine proves it never culls a poking sphere.
"Testing six planes is exact for spheres." Kept, corrected. The point test is exact; the sphere test is conservative — it can keep a fully-outside corner sphere, but it never discards a visible one.
The red team's move: flip the left plane's inward normal so it points outward. Now genuinely visible points on the left read as culled — the inside-iff-all-six invariant is broken.
Flip the normal and its signed distances change sign — visible points on that side are wrongly discarded. The witness (window 7) recomputes, disagrees with the known anchors, and turns red. Nothing is faked; the attack is real and it is caught.