I’ve spent countless hours and a considerable about of energy on getting my ray tracer up and running, and this is what I have achieved:
While it may look like modern art[ref]Actually, since art exists independent of intent and as a result of a observer-entity interaction, this picture would be “art”. Whether it is modern art rather than some other school I hazard no guess.[/ref], it is actually a rendering of two triangles in 3D space complete with color gradients and perspective. And I’m pretty proud of this, but let me provide a modecum of background before we continue.
A ray tracer in the simplest sense is any method whereby a ‘ray’ is sent out and used to measure some quantity. Imagine this working as the inverse of the way our eyes work. When we see an object was is actually happening is a light ray is traveling from a light source, like the sun, and striking upon the object. The ray then bounces off the object and strikes our eye in turn, and we get to ‘see’ the object. Not a whole lot of mystery here, and a ray tracer is not much different–just opposite.
In ray tracing the ray originates in what we might call the ‘camera’. From the camera the ray can travel, bouncing off objects as it goes, and it updates its ‘state’. So what I mean by state is imagine a ray leaves the camera and strikes a blue object. That ray is now ‘blue’. Or say a ray hits a mirrored surface, the ray’s color hasn’t changed, but it’s direction sure has. Ultimately, when enough of these rays have been sent out, an image can be compiled, like the one above.
When leveraged for rendering, ray tracing can produce some of the most realistic results of any rendering technique. While most of the methods to yield these so called ultra realistic renderings are well beyond me, some of them are conceptually straightforward. Imaging rendering a scene where the morning fog is lifting or where there’s a pool of water. In both cases, the ray offer a natural way to understand that interaction by attenuating the ray in the first case or by redirecting the ray in the latter.
Enough on ray-tracing itself, what I would really like to comment on is why I would code a ray tracer and why it took me so long.
There are entire platform suits designed to create, model, and then render images using a whole variety of techniques including ray tracing, so why would I ever want to build my own? I certainly didn’t imagine that I would make a better one, nor a more efficient one. In fact, compared to what I can do in 5 minutes in Blender, two triangles is a far cry from any great achievement. Ultimately it comes down to my desire to learn how to do it.
The fact that it took me so long might not be obvious to non-programmers, and in some ways I’d agree (or at least would like to). I set out to build a ray tracer armed with nothing more than a bit of experience using java for ‘toy’ programs and a bit of ray tracing theory. That is all, I purposely didn’t look up “how to ray trace” or read up on any of the deep theory that surrounds the field. Instead I wanted to reinvent the wheel, so to speak, and stumble upon solutions in the best way possible: in the dark.
It took a while, especially figuring out ways to implement my rather shoddy linear algebra conceptions of what to do, but in the end I’m better for it. I could not agree more with Nietzsche’s claimed that “was mich nicht umbringt, macht mich stärker” in that I’ve certainly achieved more during the process of crafting my program that I would have learned any other way. This brings me to my overarching theme that I am trying to show.
For those who know me know that I can be a tad extreme in what I take on as challenges. Whether its an ultramarathon, writing a book, or simply learning something new, I infinitely prefer going for the impossible rather than settling for the mundane. This ray tracing project is simply one more challenge that I did my best to achieve and found joy in the striving to reach it.
It should also go without saying that not every challenge need to be completed to be a success.
Here are a few unsuccessful attempts: