As mentioned in my first post I discovered an old piece of software I wrote for generating 3D images from basic primitives using simple, recursive raytracing techniques. I've given it a name change; it's now known as "SharkyTracer" (I was never good at thinking up names for software projects) and I've quickly wrapped it up in an MFC / C++ shell using Visual Studio. No screenshots of the interface and UI yet though as there's nothing worth showing.
The first steps were to implement basic point lights, a plane primitive, a sphere primitive, a material system and a simple diffuse lighting model to actually light the scene with. The test environment consists of 6 infinite planes that intersect to form a closed box area in which I placed 3 spheres and 3 coloured lights. The initial results were:
Basic - Diffuse Shading by
SharkyUK, on Flickr
Following on from this I coded an improved lighting model; and made use of the Phong lighting model and specular material components. This produced the computer generated look and feel we tend to associate with old-skool computer graphics! The results are shown below:
Basic - Phong Lighting by
SharkyUK, on Flickr
For the record, the 3 coloured non-descript dots are used to simply show where the light sources are positioned in the world.
Next up, having calculated the basic scene colouring, was to shoot an additional 'bounce' ray from where my light rays hit primitives in the world. This ray could then be used to generate reflections. The following scene was rendered using a trace depth of 2 (primary ray + 1 reflection ray). As we are only performing one bounce, we don't get a true reflections where we have inter-reflections between objects.
Basic - Refl 1 by
SharkyUK, on Flickr
The same scene was rendered again with a trace depth of 4 - hence we now pick up more inter-reflections between objects:
Basic - Refl 2 by
SharkyUK, on Flickr
Some objects, like glass and water, allow light rays through them as well as generating reflections. Hence I updated the material properties so that primitives can have a refractive index and thus I can trace refractive rays through them. This resulted in the following image:
Basic - Refl, Refr by
SharkyUK, on Flickr
At this point in time I had a basic system but the rendered primitives looked a bit floaty due to the lack of shadowing. So... I implemented basic shadowing to give the scene some depth. As each ray is traced from the view point and hits a primitive, I then shoot a ray from that hit point to lights that contribute to the hit object's final illumination. I can then check to see if that fired ray hits another primitive. If it does then it tells me there is an object between the object I hit and the light, hence some level of shadowing is evident. For now my code only renders hard-edged shadows as my current system is not optimised for the additional work needed to generate soft shadows. This is for a future version! The scene now looks like:
Basic - Refl, Refr, Shad by
SharkyUK, on Flickr
For this first body of work I decided to wrap it up by adding some very simplistic fogging to the scene - supporting 3 different distance-based modes (one linear, two exponential). The first is a linear increase of fog density between one distance and another, which results in:
Fog - LINEAR by
SharkyUK, on Flickr
The second technique uses an exponential falloff as a function of the (distance x fog density), resulting in:
Fog - EXP by
SharkyUK, on Flickr
The third technique also uses an exponential falloff as a function of the (distance x fog density) squared. This produces:
Fog - EXP2 by
SharkyUK, on Flickr
And a side-by-side comparison of the three fog modes:
Basic Fog Comparison by
SharkyUK, on Flickr
And so concludes the first part of the SharkyTracer revival! LOL!