# Project 1: Rasterizer

## Overview

Give a high-level overview of what you implemented in this project. Think about what you've built as a whole. Share your thoughts on what interesting things you've learned from completing the project.

## Section I: Rasterization

### Part 1: Rasterizing single-color triangles

We rasterize triangles naively by iterating through every point in the sample buffer and calculating whether the point is 'above' the slope of the line formed by the vertices of the triangle. We do 2 optimizations: a basic optimization by pre-computing the static slope values instead of recomputing them in the loop, and more importantly, selecting the bounds of our sample buffer carefully by computing the minimum and maximum bounds of the triangle vertices and constraining our search to that bounding box..

### Part 2: Antialiasing triangles

I implemented supersampling by adding two additional for loops to my triangle rendering code. These loops computed subpixel samples on the x and y axes. The loops were indexed against the number of samples I expected each superpixel, and in the innermost loop, we actually sample at the point computed by calculating the superpixel offsets, and then the distance expected inside the pixel based on the subpixel index, as well as + 0.5 to center the sample point inside the subpixel. Calculations were moved into outer loops as much as possible to avoid unnecessary recomputations. Supersampling works to antialias by providing more options for a pixel to be 'in' the triangle or not, so that pixels that are only partially covered by the vector triangle may be partially shaded to indicate their inclusion relative to the main triangle.

 1px (no supersampling) 4px supersampling 9px supersampling. I guess the color averaging went overboard and broke something, I'll investigate this.

### Part 3: Transforms

Implementing transforms was relatively simple. It just involved mapping the coordinates given in the arguments to the appropriate elements in a Matrix3x3() and filling in the remaining elements with the right values, usually 1.

A robot with a novel walking strategy © 2019
credit is given to the amazing Mozilla SVG documentation, which states that an animateTransform may have a 'from' and 'to' attribute that depends on that the transform is, and ends there without giving any examples. This cubeman is attempting to escape from a facility that has him in a straightjacket by performing the butterfly stroke, or something thereabouts.

## Section II: Sampling

### Part 4: Barycentric coordinates

Barycentric coordinates are a means of computing "the center" of a triangle using the coordinates at the vertices. They allow one to specify any point inside the triangle as a linear combination of the coordinates of the vertices.

### Part 5: "Pixel sampling" for texture mapping

Pixel sampling is a method where, in order to apply a texture to a surface, if the texture doesn't map 1:1 to the surface, we attempt to find a good approximation for what to map instead. The examples we implemented were bilinear and nearest sampling. Nearest sampling is relatively simple - we just get the texture pixel that's closest by multiplying u/v into the height/width and getting the appropriate texel. Bilinear sampling tries a more intelligent method, by sampling the 4 pixels in the neighborhood of the sampled pixel and constructing a linear interpolation thereof, which often results in better approximations.

 Nearest sampling Bilinear sampling (looks better and smoother)