Thursday, May 31, 2007

Software Engineering - The Formative Years

The start of it all
I have been coding since I was a boy writing basic programs (not the visual kind, the ancient line number kind) on my parents' brand spanking new TI-99. I was exposed to Pascal, Cobol and C while in high school, and I did some Visual Basic in 1998-1999. Don't get me wrong, I didn't do anything really serious until I decided to change majors in 1999 from Psychology to Computer Science.

Ok, to be fair, I didn't really start thinking hard about quality engineering until I "jobbed out" of school during the dot-com era. I found this great job writing JUnit tests for a great little company, *ahem*, that shall go nameless. This was in September of 2000. I was hired to write unit tests for the entire application, in the neighborhood of 500k lines of J2EE code. Sounds great you might say, too bad the application was set to ship just a month or two after I began.

Let me back up some and explain something about myself. I am eternally curious. Not just the fleeting kind of curious, but the consuming kind, you know, you can't stop thinking about something until you have uncovered all aspects of how it works. As a kid, it was my bike. I tore that thing apart several times in vain attempts to get my Huffy working better than my friends Mongooses and Predators (oooh, ahhh). I added a freewheel, new rims, changed multiple tires, changed the cranks, bottom bracket, removed the fork and handlebars... Anyway, you get the idea. As a teenager it was, uhmmm, girls. I didn't fare so well on that one. If you have them figured out, I could go for a few pointers.

Still on the topic of me (yes, this is still relevant), I have two more traits that contributed to me starting down the road of Engineering Software. First, is that I have never ending ideas on how to improve something. My wife particularly enjoys, *ahem*, this one. For every complaint, I always start thinking about how to solve the problem and make it better. (This topic is a whole blog in and unto itself, suffice it to say I have learned to keep my mouth shut and just listen. Most of the time...) ;) Finally, I have a healthy disrespect of the status quo, if that status quo does not conform to my standards. This one drove my parent's nuts, still does. :) I'm just not satisfied with something that is subpar. (For those that know me, I will now pause and let you pick yourselves up off the floor.)

Now, back the regularly scheduled discourse. Being that I was now getting paid a lot of money to write code for Nameless Company, I wanted to do it right. I became curious about how to solve a problem The Right Way(tm). I remember scheduling a few meetings with the lead architect at said Nameless Company, specifically so he could impart his vast wisdom of how to design software. When the day arrived, we walked into the conference room and I asked, point blank, "How do you design software?". His response was a paltry "I don't know, you just do", and no that isn't really a paraphrase. The meeting lasted a grand total of 15 minutes, the other meetings were canceled. I continued doing my job at Nameless Company, and the entire engineering team, myself included, got laid off about 5 months later in March of 2001.

Huh? How was that the start of it all?
Now, why did I tell you this story? Think back to my intolerance of things that do not measure up, coupled with my curiousity. This architect's answer got under my skin. I was not ok with his answer, it didn't fit with what I expected, and there was no way on earth I would ever accept it as the answer to my question. So I started looking for the answer myself. I spent many nights at Barnes and Noble reading anything I could find on software design, software engineering, etc... I finally purchased and read The Pragmatic Programmer by Dave Thomas (not the Wendy's guy) and Andy Hunt. That book launched me into a whole new world of programming, one of principles not heroics and black magic, in short, Software Engineering.

Stay Tuned
Thats it for now. I will post more as I gather my thoughts. This was more of a narrative of the beginnings of my career and how I started to really be passionate about software engineering. Stay tuned...

Monday, May 21, 2007

Quick Update

I spent some time this evening, adding shadows to my ray tracer. I also spent the weekend refactoring the code to improve its structure. So, basically, I spent a few hours busily working on the ray tracer, with no real rendering features added. I did improve the cohesion and modularity of my Primitive class, though. That's really cool...really...it is. *sigh*

You can see the new images on my flickr page.

See a slideshow below:

Created with Paul's flickrSLiDR.

Tuesday, May 15, 2007

Correct Reflections and Specular Lighting

Well, this is the first big milestone in the project. My ray tracer now actually renders something that looks believable, abstract, but believable. I corrected the bugs in the reflection ray calculations so reflections now show up on the correct side of the sphere. In addition, I added specular highlights as well. So now the spheres look like shiny balls that reflect their surroundings.

The algorithms are grossly inefficient. I don't really care at this point. :) I will have to go back in and refactor a lot of the code to fix the naive assumptions I made about ray tracing as I was just getting started. I only have one picture to post at this time. I am in the middle of upgrading my linux distribution from gentoo 2006.01 to the 2007.01 profile. This basically means I have to recompile every single library and executable on my machine. Since the dependant libs must be compiled first, sometimes apps stop working periodically. Apps like my ray tracer. *sigh*

I still need to add shadows. I couldn't get it to work before, but I think that fixing the reflections, will fix the shadows as well, since calculating the shadow rays, reflection rays and surface normals are very, very similar. I'll post more images when I can.



I decided to start using flickr for the renders I post. I added a few more renders, you can see them here.

Monday, May 7, 2007

Ray Tracer: Reflections

Ok, so this is quickly becoming nothing more than a blog to chronicle my progression through creating a ray tracer. I've decided to give in to inevitability and simply accept that this is a ray tracing blog. So, I will now feel free to dig into some more detail. For those of you who just want to see the pretty pictures, feel free to ignore the text.

Apparently, Brandon didn't like the verbal beating I gave him in the last post (yeah, he's *that* petty). :) He ran off and created his own ray tracer, with his own associated blog (http://brandonray07.blogspot.com). Not to be outdone, I simply have to update my blog. I must say though, he copped out and is writing his ray tracer in Ruby. I love ruby, I do, its a sweet language. It also isn't very fast for things like ray tracing. In essence, he is cheating (yes, I am *that* petty). :D

I have to admit I am stumped on the shadow ray code to detect if a surface is in shadow. I have spun my wheels on that piece of code for at least a week. I decided to push ahead and go for reflections and specular lighting. The reflections piece is fairly simple. If a light ray hits something, it bounces off. I just have to calculate the angle at which it reflects and the handle the reflected light ray just like any other ray. This is a really cool concept and it is one of the key benefits of ray tracing. It is also simpler to implement than I thought.

As a fortunate side effect of the reflections, I think I finally have a clue what is causing the shadow ray code such difficulty. The sphere's are rendering as though they are both opaque and completely transparent. You can see this in the middle sphere in the reflection images below. The reflection of the blue sphere should be hidden from the camera, but it is being "projected" onto the inside of the sphere on the opposite side of the sphere. Anyway, It is tough to explain, but its plain to me. Since I have to fix it, that works well. :)

Enjoy the latest images:


Friday, April 27, 2007

MRTS (More Ray Tracer Stuff)

I took some time out of working on the ray tracing algorithm to fix a few nagging bugs and make it easier to specify the scene that I am rendering. I fixed the bug that caused spheres to render distorted if they were off center. I also fixed the lighting code and fixed a bug that caused any sphere not at the origin to be incorrectly shaded. Probably the biggest change was to move the definition of the scene outside of the code and into a data file. Now I can change the scene very quickly without a recompile. That is very handy for testing, and for just having fun with it to see how the lighting model behaves if I move a sphere or there, or change the light sources, etc...

Here is a sample XML scene definition, and the image it created. For my co-worker (*ahem* Brandon) that takes issue with rendering the light sources... DEAL WITH IT! :D

 
<scene>
<light_sources>
<color name='blue_light' red='0x00' green='0x00' blue='0xff' />
<color name='red_light' red='0xff' green='0x00' blue='0x00' />
<color name='white_light' red='0xff' green='0xff' blue='0xff' />

<sphere x=' 5.0' y='-5.0' z='-2' radius='0.1' color='white_light' />
<sphere x='-5.0' y='-2.0' z=' 4' radius='0.1' color='white_light' />
</light_sources>

<objects>
<color name='clr' red='0xff' green='0xff' blue='0xff' />

<sphere x=' 0' y=' 0' z='0' radius='1.5' color='clr' />
<sphere x=' 0' y='-10' z='0' radius='1.5' color='clr' />
<sphere x=' 0' y=' 10' z='0' radius='1.5' color='clr' />
<sphere x=' 10' y=' 0' z='0' radius='1.5' color='clr' />
<sphere x='-10' y=' 0' z='0' radius='1.5' color='clr' />
<sphere x=' 10' y=' 10' z='0' radius='1.5' color='clr' />
<sphere x=' 10' y='-10' z='0' radius='1.5' color='clr' />
<sphere x='-10' y=' 10' z='0' radius='1.5' color='clr' />
<sphere x='-10' y='-10' z='0' radius='1.5' color='clr' />
</objects>
</scene>

The purpose of this scene is to show how the light is reflected differently off each sphere depending on where the light sources are. With no further delay, here is the image:


And since Brandon wants to see code so badly, here you go:

int main(int argc, char ** argv) {
// do stuff
}

Till next time, when I plan to add either anti-aliasing, secondary rays, or specular lighting, or perhaps some combination of those items. Stay tuned!

Update:
So I outdid myself. It is apparently really easy to add antialiasing to a ray tracer. It just kills performance. The main gist is this, instead of sending out just one ray per pixel in the image, I send out 4, each offset slightly, I then take the average of each ray and set that to the be value for the new pixel. Here is the same scene above with antialiasing. Notice how the sphere's boundaries are not so pixelated, they are smoother. Now, I just need to generalize the code to handle any number of rays per pixel, not just four. I'm getting ahead of myself. Enjoy the image:

Saturday, April 21, 2007

More Ray Tracer Stuff

I have been asked what a ray tracer is. Simply put, (haha, I know it sounds crazy that I'd assocciate simple with it...), a ray tracer is a piece of software that models rays of light and the physics that govern them. Think of an image captured by a camera, now think of how the light got from the sun to the photographic medium. It all starts out some 93 million miles away as the sun radiates light in all directions. A miniscule fraction of those light rays travel that 93 million miles, pass through the atmosphere, hit the grass, trees, water, mountains, people, goats, and whatever else you may be in the your scene. Each time the light hits a surface it bounces off and makes it through the lens of the camera and gets recorded on the film (or SD card).

That is exactly what a ray tracer does, except in reverse. It would be horribly wasteful to calculate all the rays that eminate from a light source, in hopes that a few will eventually make it to the image. Instead, a ray tracer starts with the simplifying assumption that the only light rays we care to map are the ones that actually make it to the camera, and so that is how the processing is done. Conceptually, we just shoot light rays backwards through the scene and bounce them off objects in a scene and if the ray eventualy hits a light source, then we know that we can color the corresponding pixel of the image according to the objects that the ray bounced off from. In all, its a lot of trigonometry.

And, in answer to your question Dad, it is exactly the same as a mathematical ray. I have been visiting Wikipedia, a lot, to refresh my brain on the quadratic equation, vectors, dot products, and general trigonometry. As a sampling, I took the equation for a 3D sphere and the equation for a ray/line and solved to find the distance along the ray where the ray intersects the sphere, this is the result:
I then solve that equation and, voila!, I know if a ray hit the sphere! Got it? ;)

Here are some images of the latest work on the ray tracer. I added light sources and some diffuse shading of the sphere. The sphere now actually looks something like a sphere, and less like a plain circle.


This the first image I rendered where it actually looks like a sphere. The light source is off image to the upper left. My heart skipped a beat out of sheer surprise when it came out looking so clean and clear (and correct). :)

This image is after a few hours of bug fixing, and adding in a ambient light factor. This is an image of a blue sphere with two light sources, way off in the distance, they are visible in the image as two white dots to the upper left and right of the sphere. Notice how the shading of the sphere is different based on the position of the light sources. The upper left light is further away, and so its shading is different.

Now, I just need to blog about something that is not ray tracing related, lest this become a ray tracing blog. *hrmm...* Forget it, I'm pretty focussed on this thing for now, I fully intend that this ray tracer becomes part of a software portfolio that I can share with future prospective employers. Till next time...

Tuesday, April 17, 2007

Ray Tracer II

Turns out I was debugging code that wasn't buggy. If you look in the pictures below, you will see that the spheres that are off-center are distorted the same thing can be found here. So, I added more spheres to the scene. Each of these spheres have the same radius and the four groups of spheres, top left, top right, bottom left and bottom right, are all positioned directly behind each other. The only difference is that they are all placed at different distances away from the camera. The perspective is near impossible to see with the current coloring scheme, but I'll get that working soon too. I also played around with the camera a bit, moving it left, right, and zooming in. The resultant images can be found below.

I know this doesn't seem like much, but its pretty cool that the spheres are all properly scaled and the perspective is correct without any special code. I just move around the camera and the objects in the scene, and everything gets correctly displayed. Its really cool, really... *sigh*

This is original image with the camera centered:

This is the same image with the camera still centered, but zoomed in:

This is the same image with the camera moved to the left:
Once again, the same image, but this time the camera is moved to
the right: