CPU Rasterizer

Rasterization, Z-Buffering, Anti-Aliasing, Bresenham's Algorithm C++, GLM, QT

Vertex Processing

Create a camera class, and create a view & projection matrix from that camera Apply view & projection matrices to mesh to convert it into screen space.

Rasterization

Loop through each triangle of the mesh and test pixel row intersections. Create a bounding box around each triangle to optimize row intersection tests.

Barycentric Interpolation

Use Barycentric Interpolation to determine attributes of each fragment. Make sure to use persepctive-correct Baryentric interpolation in 3D, since the distance between vertices is no longer linear after perspective divide. We will not only be interpolating color values but also UV coordinates and normals for texturing and lighting.

Fragment Processing

Before we set a fragment as a pixel of a final render texture (in this case it was a QImage), we must conduct a z-buffer test, and only replace the pixel value if the fragment’s z value is smaller than the current one. In this implementation we used a 1D array for faster access.

Results

Results have been shaded using the Lambertian reflection model

Toon shading implemented by clamping the lambert value to constant values depending on their range.

Supersampling Anti Aliasing

Each pixel is subdivided into a grid of subpixels. You render at that higher resolution, then average the subpixel colors to get the final pixel color. Triangle edges that would normally look jagged now blend smoothly. This image was smoothed using 2x2 supersampling.

Triangle images from: CIS 5600 Rasterization - Adam Mally