Oogst's raytracer

I have written my very own raytracer, just for the fun of it. I have tried to build in all the features that are in the good raytracers, like Brazil. Of course, that is way too much work to actually do, so I never got it finished. I did get a load of nice features in, though, and beneath this text you can see what I did make.
My raytracer does not work with any modeller, so I had to model my scenes in-code. Modelling in-code is hell, so that's why you will not see any flashy models or great compositions rendered with my renderer. I once hoped to make my renderer work with Blender, but I never got that finished, so instead you should enjoy yourself with the cubes, spheres, cylinders and planes that are shown below.

The features

The history

First render
2 december 2003:
My very first render. Eight polygons and one light. Snif.



Corrected diffuse model
3 december 2003:
OK, so the previous one did suck. The diffuse lighting model was incorrect and this is how it should have been.



Boxes
6 december 2003:
I implemented a function to create boxes. I also discovered a major glitch in my intersectioncalculation, resulting in errors when polygons are exactly parallel to either the XY-, the XZ- or the YX-plane.



Shadows
7 december 2003:
Shadow feelers added.



Adaptive anti-aliasing
7 december 2003:
Anti-aliasing added. The choice is for one, five or nine samples per pixel and this is chosen adaptively according to a set threshold. To do this nicely I made my renderer a bucket-renderer. More exactly: a block of 50*50 pixels is renderd with only one sample per pixel. After that all the contrasts between adjacent pixels are checked whether they are above a given threshold. If the contrast between some two adjacent pixels is above this threshold, then more samples are taken for these two adjacent pixels.



Lamer area-light
9 december 2003:
A test to build a lamer area-light like in POVray. Just a bunch of weak lights very close to each other.



Cylinders
16 december 2003:
I implemented a function to create cylinders with a setting for the number of segments.



Spheres
16 december 2003:
After cylinders, spheres were the next in line. And for the first time: statistics. In Dutch, though. The number of intersectioncalculations (the number at the bottom) is already so high that a double is needed to cover it fully.




Reflections
16 december 2003:
The most fun to add, for it is so simple and the result is so cool: reflections.



Bounding objects
20 december 2003:
To speed things up a bit I added bounding objects. The boxes, cylinders and spheres are all placed inside a perfect mathematical sphere. Every ray is now first checked with the perfect sphere (which can be done very fast) and only if that is intersected are the polies inside it considered. This brings the rendering time for this scene back from 709 seconds to 31 seconds. Also, the number of intersectioncalculations is lowered from 12 billion to 690 million.





Animation
20 december 2003:
One of my friends wanted to see an animation of my renderer. So that's what I made. The coolest bug so far was uncovered here: after 70 frames this tiny little program consumed about 2,5gb memory. After filling these memory leaks it went down to a constant amount of memory of less then 5mb. Due to a lack of space on my server I do not have the animation online, however.

Specular lighting
21 december 2003:
What every woman wants: shiny objects. To me, its just specular lighting. Might help me in my social life though.



Skylight
22 december 2003:
A brute-force skylight has been implemented. Rays are cast randomly, resulting in a very noisy image. This one took 300 skylight samples for every pixel and still the result was this bad. Testing revealed that 2000 samples was necessary for a smooth image this way.




Global illumination
22 december 2003:
If skylights and reflections can both be done, than global illumination can be done as well. Here the strength of the global illumination has been set to five times as much as would be realistic, just to show the effect. Again, this pic is very noisy with its 150 samples per pixel.




Skylight with equal ray distribution
23 december 2003:
This is a better way to do Monte Carlo: I have written a function to equally distribute the rays along all directions. The result is a much smoother skylight, again with 300 samples. This one had a rendering time of about 6 minutes. Not bad, as I am not doing undersampling yet.




Generalized camera
24 december 2003:
OK, I know, I should be ashamed that it was not added until now, but I've done it now, so stop yelling at me. I am talking about creating a general camera, of course, with a position and a target point. The pic also shows the fact that lights can be coloured, though that is not a new feature at all.




Improved ray distribution for the skylight and the global illumination
26 december 2003:
The distribution-function I wrote for my skylight still has some problems. Objects that are high above the ground have a visable shadow on the ground:


Object have strange shadow-edges:


So, I decided to visualize my distribution-function. With the sampling rate set to 4, this is how the samples are distributed into the directions:


Looking at this, it is clear what is wrong with my distribution-function: way too many rays are shot almost straight up. I changed the formula from the complex thing I had to a simple form of the stratified sampling pattern, resulting in the following ray-distribution:


All in all, the new result is quite a bit more noisy with the same number of samples, but the problems mentioned above are solved:



Self-illumination
26 december 2003:
I added self-illumination and as I already had global illumination, that made for free area lights. Very inefficient area lights, though, yet with a cool effect:




Smooth shading
27 december 2003:
Finally, one of the things that were missing most until now: smooth shading on flat surfaces. Unfortunately, a bug remains somewhere in the code, so the results are not totally correct yet. The cylinders here are smooth-shaded:



Glossy reflections
27 december 2003:
I got totally bored of searching for the smooth shading-bug, so I decided to implement something more easy: glossy reflections. The strength of the gloss and the number of samples can be set. Here the ground plane has glossy reflections.




Smooth shading revisited
28 december 2003:
Previously, I tried to make a smooth-group system where my polygons would semi-automaticaly detect the smooth-group they were in. While I was unable to find all the bugs in my algorithms, the thought entered my mind that smooth-groups are actually something the modeller should do. So, I cut that part out and made my cylinders and spheres calculate their own smooth normals. Still, some glitches remain, yet the result is now available for my spheres as well:



Texturing
28 december 2003:
The functions I implemented for smooth shading were almost all that was needed for texturing as well. So here it is:



Normal mapping
29 december 2003:
Normal mapping is quite easy as well, now. Unfortunately, this does not work with smooth shading for the moment and it only eats normal maps, not your regular height maps.



Advanced texturing
30 december 2003:
Now all material-settings can be controlled using textures.


Click here for a high-res version of this render.

Texture filtering
31 december 2003:
I solved the problem with the combination of normal mapping and smooth shading. More interesting though: the user can now choose between nearest neighbour texture filtering (on the left) and bilineair texture filtering (on the right):



Spotlights
1 january 2004:
Another basic feature, this time spotlights. In this pic the smooth shading error with the spheres is painfully visible.



Direct lights
2 january 2004:
After spot lights come direct lights. A direct is a bundle of paraller light. This does not exist in the real world, except in lasers, but it is used quite often in 3d-graphics, for it nicely simulates a light source that is very far away. The difference between a spot and a direct is quite hard to see when the bundle of light itself is not visible, yet to show a bit of the effect I placed a spot in the left half of the image and a direct in the right half.



Attenuation
3 january 2004:
Another feature for the lights: distance attenuation. A lineair fade out of the amount of light as the distance to the light increases. In the left of the image there is a spot, in the middle a bunch of omnis and in the right a direct.



Soft light bundles
3 january 2004:
I added soft light bundles. The softening happens lineair and the starting distance from the centre of the bundle of light can be set. The three lights on the bottom of the image are directs, the other three are spots.



Fog
3 january 2004:
Another simple feature: distance-fog. The left half of the pic shows exponential fog, the right half shows lineair fog.



It is also possible to set the fog to not influence the background. This looks quite cool:



Object-lights
6 january 2004:
They are not totally correct yet, but still great fun to play with: object lights. I currently use a Monte Carlo version of object-lights: lots of rays are cast towards the light-source. You can make any random polygon a light source and its diffuse colour will be taken into account, as can be seen in this picture:



Corrected smooth shading
9 january 2004:
Woei! I finally fixed the problem with the smooth shading, which turned out to actually be three problems. To celebrate this I made me a nice render, combining an object light and a skylight.





Added specular softening
13 january 2004:
To make sure specular lights neither light the back of objects nor have hard edges, I added specular softening. This is, of course, texture controlled, as all material parameters are. From left to right the following softening values were used: 0.0 - 0.2 - 0.5 - 1.0 - different per color channel.

To do-list

A lot of things are still screaming to be implemented, this is a list of some of them. As I ceased working on this project years ago, I will definitely not implement them anymore, but this is what I once planned to still add: