Zachary W. Huang
I’ve always found computer graphics intriguing, especially the subfields of ASCII art/animation.
One of the first ‘cool’ things about the command line I discovered was that you could type in
telnet towel.blinkenlights.nl
and watch an entire Star Wars movie through ASCII drawings.
Another animation that fascinated me was donut.c
, which displayed a spinning donut using only ASCII characters (and with donut-shaped C code).
I had previously forayed into the world of ray tracing, but it never really worked out well. However, I soon discovered Ray Marching, a method of generating graphics which can be easily adapted to 3D ASCII animations. There was no way I wasn’t going to try this out.
The one key ingredient in ray marching is the Signed Distance Function (SDF). An SDF is a mathematical function that calculates the shortest distance from a vector to some 3D surface. Using an SDF, we can march rays forward by the maximum distance before they potentially hit a surface. This is more efficient than ray tracing, which marches all rays at a small, fixed value. Once the SDF for a ray becomes close to 0, we know we have hit a surface. To calculate shading on that surface, we need to know the surface normal, or the vector pointing perpendicular from a surface. With an SDF, this is easy - the surface normal is simply the gradient of the SDF at its surface. This is because the fastest way to increase an SDF at a surface is to travel perpendicular to it. Then, we can convert the shading information into ascii characters to generate a frame. For more information, you can check out this article.
Now, for the results!
Julia made it very easy to work with math expressions and get good performance out of it too. With stack-allocated arrays and multithreading both an import away, the ray marcher could easily render at 60 frames per second.