Master the fundamental concepts of software rasterizer through this focused micro-challenge.
You have read the whole brief, and the concepts above stay free on every task. Writing and running the code needs a plan.
Three hints are available for this task, revealed one at a time inside the code workspace so you can struggle productively before seeing them.
Every task includes starter code, theory, and hidden tests so you can implement and verify locally in the browser.
How it worksA closed 3D model has outward-facing front triangles and inward-facing back triangles. When the camera sits outside the mesh, back faces are never visible. They would be hidden by front faces and the z-buffer anyway.
Back-face culling skips rasterizing away-facing triangles. For closed opaque models, this eliminates roughly 50% of triangles before any per-pixel work begins. OpenGL, Vulkan, and Direct3D enable it by default.
For triangle vertices A, B, C in counter-clockwise order (front-facing):
cLoading…
For example, a triangle on the XY plane facing +Z with camera at (0,0,5) has N pointing toward the camera and survives. A triangle facing -Z gets culled because the normal points away. The dot product measures cosine of the angle between normal and view vector; negative means angle > 90 degrees.
You will implement the culling test for a set of triangles and count survivors. This task requires computing face normals via cross product and comparing against the camera position. Wrong winding order when importing Blender or Maya meshes is one of the most common bugs in custom renderers.
Decide which triangles face the camera (back-face culling) with exact 3D integer arithmetic, three ways:
n·(eye - A) > 0, with n = (B-A) × (C-A).# starts a comment line.
cLoading…
NAME: degenerate (zero normal), discarded and counts in no total.d = n·(eye - A), computed in 64-bit. With front cw, every sign is negated. d > 0 is front, d < 0 is back, and 0 is edge-on.x' = (x - ex)/(ez - z) and y' = (y - ey)/(ez - z). Only triangles with every z < ez can be projected; otherwise print n/a (not in front of the camera). The sign of the projected area is the sign of det[[X0, Y0, D0], [X1, Y1, D1], [X2, Y2, D2]] with X = x - ex, Y = y - ey, D = ez - z, adjusted for the winding. Append (MISMATCH) if it disagrees with the world test (it never should).(B-A).x·(C-A).y - (B-A).y·(C-A).x, adjusted for the winding. Append (wrong) when it disagrees with the world test.cLoading…
; N not fully in front of the camera when any triangle could not be projected. With front cw, the header says clockwise.camera: X Y Z (within +-1000), front: ccw|cw, tri: NAME AX AY AZ BX BY BZ CX CY CZ, tri: coordinates within +-1000, at most 16 triangles, unknown command X.Input:
cLoading…
Output:
cLoading…
Hidden tests cover an oblique triangle that fools the shortcut, a triangle behind the camera, an edge-on triangle, clockwise winding, a camera looking from the other side, and input errors.