I have forgotten how hard.
The first time I got wind of ray tracing in computer graphics was when I was scouring the shelves of a computer book store at the annual Computer Faire in Johannesburg. This must have been in something like 1992, or 93. The book in question was Photorealistic Ray Tracing in C, by Christopher Watkins, and it included the most amazing samples of images produced using ray tracing, it explained how it worked, and even included two 3.5″ floppy disks (we called ’em stiffies, go figure) with the example source code and everything.
Mind you, at that stage I was still wrapping my head around Pascal, and had null experience with C, so all I did was read, look and think.
So in the past week I started getting interested in building a ray tracer again, so I figured I’d start from scratch. It is not necessary to completely reinvent the wheel – thanks to the internet – because all the info is out there. The problem is that the only place where it is all available in one place is in the source code of the numerous open-source tracers. Many of them also have feature sets that go beyond mere ray tracing, and include things such as stochastic ray tracing, path tracing, photon mapping, bidirectional tracing, Monte-Carlo tracing and esoteric stuff like Metropolis Light Transport and radiosity.
All of which means that to implement the basics, one has to trawl through forums, dig around for papers, and use brute force trial and error. Here then, are some of my initial mistraces:
bug001 - Errors in sphere/ray intersection
bug001 is a direct result of errors in sphere/ray intersection. Don’t know why it turned out so funky, but it did. It is a feature dammit, not a bug!
bug002 - Reflection works
bug002 happened when I got reflection to work properly, with shadows. Not technically a bug. Let’s call it a work in progress.
bug004 - interesting twists
This is definitely one of the buggier ones. Mostly because it appears as if I screwed up reflection here, you think. No, I was actually trying to implement refraction. Ha!
At the moment I have both reflection and refraction going, but I am rewriting some of the internals to make it more parallelizable. I also have plans to move port the tracing code to the GPU, via GLSL. Which will be hilarious, given my current dependence on printf-debugging just to make this simple code work…
- ortho and perspective camera models
- two object types (sphere and plane)
- one light model (point light source)
- ambient, diffuse and specular surface
- shadows (only ambient lighting)
- reflections and refractions
Of course, I’d like to add all the other stuff too: one man’s feature creep is another man’s late night braingasm.
- Other primitive types, including “discreet” types like polygons
- Kd-tree implementation to speed up ray/primitive intersection
- Anti-aliasing using one of the acceptable methods (more forum trawling/experimenting)
- Procedural textures (keep your fork, there’s Perlin!)