Rasterization
I found an excellent tutorial called, Rasterization: a Practical Implementation, on a site called Scratchapixel that explains the rasterization process and provided an implementation on the CPU in C++. Rasterization is essentially the mechanism the GPU uses to convert geometry into a raster (pixel) image displayable on the screen.
I decided to write my own version in JavaScript and expand on it to eventually reach the point where it does what WebGL does. Not terribly practical, but an excellent learning process. As always, view the source code to see the details of what is going on.
The triangle and mesh implementations are nearly direct conversions of the code from Scratchapixel.
The next implementations are my expansion on the concepts. Each is specific to the rasterization process for different types of geometry. I chose to use the Digital Differential Analyzer (DDA) algorithm to raster the lines because it is simple, but it turns out not to lend itself well to line width, you can see that pixels get missed. I plan to try Bresenham’s Line Generation algorithm next as well as using triangles to generates lines as I did in this WebGL example.
TODO: raster circle
TODO: raster polygon
TODO: raster text
TODO: raster sphere
Raster final is the culmination of everything. I decided to write a CPU based functional equivalent to WebGL, or at least a portion of it: vertex and fragment shaders, uniform, attribute and varying parameters, color and depth buffers, 7 draw modes, etc., to get a better understanding of what might be going on under the hood. The rasterization concepts I learned above have allowed me to get nearly identical results to the WebGL comparison below. Performance is orders of magnitude different from the GPU, but the visual appearance is nearly identical.
This turned out to be a lot of fun and I will likely be back expanding on this over time to implement more and more WebGL functionality.