Clipping
Cutting triangles against the view frustum’s boundaries in clip space, before the perspective divide — not an optional cleanup step, a mathematical necessity.
Why it must happen in clip space, before the divide
The view frustum test in clip space is a set of linear inequalities on the homogeneous coordinates:
Because these are linear, a triangle edge crossing one of these boundary planes can be clipped with a simple linear interpolation — find the parameter where the edge crosses the plane, and every attribute (including itself) can be linearly interpolated to that and still be correct, because nothing has been divided yet.
If you divided by w first (going to NDC before clipping), the mapping is non-linear. A straight 3D edge does not stay straight under this mapping in general — clipping against straight-line boundaries in already-divided space would require intersecting with curves, not lines. Clipping is done in clip space specifically to keep the intersection math linear and simple.
Why it must happen at all (not just “for cleanliness”)
Points at or behind the camera have . Dividing by a zero or negative either blows up (division by zero) or flips the sign of every coordinate (a point behind the camera would get mapped to seemingly-valid NDC coordinates on the opposite side of the screen instead of being correctly recognized as off-screen). Near-plane clipping specifically exists to guarantee every vertex that survives to the perspective divide has .
Where actually comes from
For a typical perspective projection matrix (OpenGL-style, right-handed view space where the camera looks down ):
Multiplying by a view-space vertex gives . Since visible points have in this convention, comes out positive — this is why the negation is there, purely to keep positive for points in front of the camera. (See Coordinate spaces (rendering pipeline) for the sign-convention note on vs — depends on how your source defines .)
Pipeline placement
Camera Space --Proj_Mat--> Clip Space --[CLIPPING HAPPENS HERE]--> perspective divide --> Screen Space (NDC)
Related
Coordinate spaces (rendering pipeline)
Perspective-correct interpolation
Back-face culling