Jon Baker, Graphics Programming

    home

    writings

Software Rasterizer

  My previous implementation of a software rasterizer was able to do some interesting stuff, but it was difficult to repurpose and was not designed well. For this reason, I decided to rewrite it and make a header for NQADE which would contain the logic and make it easier to work with for future projects.

  As support for that, I also wrote a wrapper around my image utilities with all the common functions I would need, so I don't have to do lodepng::decode and lodepng::encode, I can just use the Image class's Load and Save functions. Makes things much simpler - I also needed a floating point version of this class as well, to represent the depth target of the rasterizer.

Textured Lines

Motivation

  It's a valid question, when you have a graphics API, why you would want to implement your own? There are a number of reasons to do so. Some of the largest ones that I see my implementation is capable of, over simple usage of the OpenGL API that I have been using:

  And overall it works pretty well. As a single threaded CPU process, it's not the fastest thing in the world, but it is functional. Computing on the CPU and buffering the resulting image to the GPU is in the 250ms/frame kind of territory. You can see it here being used to show the old version of the sponza model:

  Realtime output is not an application that it is particularly well suited for, due to the speed - there are a lot of other applications outside of this usage. The point of this project is to give me something for use cases outside of that, I was really just curious to see if it would do it. Displaying a higher poly textured model like this in realtime is a job for the graphics API rasterizer. Hardware accelerated implementations, or at least implementations that would operate in multiple threads are much better suited for realtime throughput at reasonable resolutions, if you want more standard functionality like that.

Barycentric Sample Rejection

  This was just a quick experiment, where I could consider or not consider samples that were in certain ranges of the barycentric coordinates on a simple icosahedron mesh.

Two Barycentric Coords Less Than 0.3

Sample 0 Color Sample 0 Depth

Mod Logic on Barycentric Coords

Sample 1 Color Sample 1 Depth Sample 1 Logic

This is the mod logic, where continue aborts this fragment and continues to the evaluation of the next one.

Another Little Experiment

  And I also tried doing some stuff with swept lines - this uses Bresenham's algorithm for drawing lines, basically a large number of nested icosahedrons, which are rotated slightly between each nesting verison. This is something you could pretty easily do with graphics API geometry, with the exception of the transparent output.

Sample 2 Color Sample 2 Depth

Gran Turismo 2 Models

  Something I was messing with during the time I was doing this - this is really cool. I found a twitter post that led me to a program called gt2mv, which I was able to use in conjunction with some other modding tools to extract a couple thousand textured low poly car models from the game ISO. GT2 was released in 1999, so hardware requirements and capabilities were very different - the modelling and texturing is very impressive, and makes really good use of the resources that were available in consumer hardware at the time.

6th gen four door Honda Civic

  They have a huge catalog of cars, even my first car, the 6th gen four door Honda Civic. Wheels are handled separately from the models, due to their integration into the physics sim on the suspension, so you would have to manually scale and place the wheels in order to make that part look right. I had an idea to stress test the rasterizer, I rendered hundreds of thousands of copies of these models to an 8k pixel square target - you can see the result below ( click through for full res, but be aware it's about 70 megs ).

  The performance is not great at this scale, especially since I was loading the obj for each model each time I drew a vehicle. Not too bad given the poly count and resolution of the textures, but still some significant overhead. This image took a couple seconds to produce - I took inspiration from the idea of a big pile of hot wheels cars, they have randomized orientations in such a way as to not show the bottom surface of the model.

hot wheels

Future Directions

  This has already enabled several other projects. I intend to use this again in the future, as it can be very useful to jack into the rasterizer process at arbitrary points. I definitely think that this will be useful again, which was the motivation to encapsulate it better and put it in a header. Two projects as of writing time have made use of this capability in NQADE:

  These both are ideas that had been on the back burner for some time, because I didn't have an easy to use software rasterizer interface. My old implementation worked well enough, it was just written in such a way as to make it fairly difficult to extend. I had followed the tinyrenderer series of tutorials when I was going through it with the GPVM group. It's a good intro to the concepts, but you have to think about how the code is structured if you want to do something more general purpose with it.


Last updated 1/1/2023