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