Raytracing

I’m taking a bit of a hiatus from perspective drawing, but I’ve learned some more interesting perspective techniques that I can share with you later, along with a really good book on the subject, but I’ve started on yet another project I’ve had on the back-burner for a while now: a raytracing engine.

At work we’ve got a little bit of downtime coming up, and one of the senior engineering guys, Bill, and myself started talking about raytracing. I don’t recall exactly how we began discussing the topic — something to do with Pixar, Ed Catmull, and him trying to remember the name of the guy that invented raytracing, and then there was a short discussing I initiated about this guy: Ron Fedkiw. Do yourself a favor and look at the videos on his site. Be prepared to change your pants and/or underpants (if you are the kind that wears underpants) during the viewing of these animations.

Our discussions on computer graphics rekindled my interest to write a raytracer. During my undergrad at the University of Southern California I took a graphics course and the last assignment was to put one together. I only got mine partially working, and had no more time during the semester to go back to the raytracer. So, I gave it up. Plus, through my over-zealous use of object oriented programming, OpenGL, and MFC, it was a horrible mess of partially functioning shit. Moral of that story: keep it simple, stupid.

Last night and all of today, I’ve been working on remedying that epic failure in my college career. Raytracing and all that it entails is an expansive subject. At it’s core, raytracing is firing (out) rays into a 3D scene and intersecting objects to return their color values. You have a picture plane (defined as a grid of pixels), and you use some vector mathematics to fire rays into a 3D scene. A ray is a point in space along with a direction. In this case, you use a point camera, and fire rays from the point through each pixel in the grid into the 3D scene. You test to see if the rays hit things in the scene…spheres, boxes, planes, what have you, and you return the color value and write it to the grid. We can get into discussing things like local illumination models, shadow casting, radiosity, super-sampling, and a whole slew of mathematically challenging topics related to image-based rendering, which I haven’t touched in a couple of years, but we won’t. Time for me to dust that portion of my brain off anyway.

The “Hello World” of raytracing is a checkerboard floor with any grouping of chrome spheres in which everything is reflecting everything else and casting shadows all around. That’s my first major goal, and this time, being a bit wiser, I’ll try and keep it as simple as I can be.

The work-in-progress of my version 0.1 raytracer:

Glenn’s Version 0.1 Asstastic Raytraced Image

Click on it to see it in it’s full 1920×1200 pixel glory.

Features so far: well it works, don’t it? It’s fairly fast. I can raytrace an image of any size. It has a simple illumination model and I can do plane and sphere intersections. All the bread and butter.

How did I go about building this program with my busy work schedule and only having scant hours available on weekends and weekdays? I broke it down into milestones that I thought were doable in a couple of hour chunks.

The first milestone was just to get the project setup. In that case, if I sudden got incredibly lazy, I could have at least the basic project setup in Visual Studio for me to continue on later. This included some math code I jacked from the Cloud game engine, Bushido and a TGA exporter I wrote a long while back. My idea is that this program will draw everything into a pixel buffer (huge ass array of RGBA values), and then spit it out as an image that I can view in Photoshop.

The second milestone was just to build a raycaster. This is the first step in a raytracer…just being able to fire rays into the scene and hit things. I kept true to my word and kept it simple, there’s no complicated scene manager or lighting models, etc. It’s currently all hardcoded. I wrote ray-plane and ray-sphere intersection tests.

The next milestone was to do a simple illumination model. Since I started writing my code willy-nilly, hardcoding things here and there, and such, you can see the lights don’t match. The purple and white plane has a light source of it’s own and the sphere’s light isn’t the same, but that’s fine, I’m messing around with phong shading, and right now it works, and it produces a pretty damn cool (and asstastic) result.

I though this would take me at least a couple of days to do…but it’s 1 am, Sunday morning, and after only at least, I’d say, 10 hours of coding between Friday and Saturday, I’ve got quite a lot of what I wanted to do.

My next milestone is to make everything a little more organized so I can do some recursive raytracing — this will allow me to get the refections, refraction, and shadows, that I’ve been dying to see in my own raytraced imagine.

Once I have that, I think I will have the start of a scene list, which I can expand to include ray-triangle intersection and generic 3D models I can import into the raytracing engine. What I’d love to do is to raytrace a Dyadin level or a the islands in Cloud. That would be pretty damn schweet.

And from there…well the sky’s the limit, and I’d love to start learning the more complicated mathematics behind all the cool stuff you can do. I have a book on procedural texturing and modeling, that would be awesome to infuse into my raytracer. You’ll be seeing more of this on the Courne Supremacy.

Oh, and I saw the Courne Ultimatum. I suggest you do the same, it’s an excellent movie.

Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Slashdot

Leave a Reply