Depth Buffer: we keep track the depth of the closest triangle seen so far
0. initialize depth for each pixel (super sample) to infinity

randomly select a not drawn triangle from buffer

for each pixel (super sample), draw that triangle if its depth value is smaller than stored value, don't draw if its depth value is larger than stored value

update new depth buffer if pixel (super sample) get drawn

repeat until all triangles are drawn

The above technique will work fine with super sample

Space: constant space per sample for depth buffer, don't depend on overlapping primitives

Time: constant time per covered sample

Transparency and Alpha

Non-Premultiplied Alpha

Over operator for non-premultiplied alpha: non-commutative blending of tinted glass

Given A = (A_r, A_g, A_b) with alpha \alpha_A and B = (A_r, A_g, A_b) with alpha \alpha_B, to compute B over A, we get: C = \alpha_BB+ (1 - \alpha_B)\alpha_AA, \alpha_C = \alpha_B + (1 - \alpha_B)\alpha_A

Premultiplied Alpha

Premultiplied Alpha: compute B over A

A' = (\alpha_A A_r, \alpha_A A_g, \alpha_A A_b, \alpha_A)

B' = (\alpha_B B_r, \alpha_B B_g, \alpha_B B_b, \alpha_B)

This is exactly how we compose RGB value (we are expressing color in homogeneous coordinates)

Premultiplied alpha is closed under composition

Render mixture of opaque and transparent triangles

render all opaque primitives in any order

disable write to depth buffer, render semi-transparent triangles in back-to-front order. If depth test passed, triangle is over color buffer, otherwise don't draw. (we need to sort semi-transparent triangles and hope they don't intersect)

Full Rasterization Pipeline

Steps:

Transform triangle vertices into camera-centered world space (inverse of camera transform)

Apply perspective projection into normalized coordinate space

Clipping: discard triangles lie outside (culling) and clip triangles to box (possibly generate new triangles)

Transform normalized coordinates into screen coordinates and to image coordinates