TITLE: A Real Heron
NAME: Kevin Wampler
COUNTRY: United States
EMAIL: wamplerk@cs.arizona.edu
TOPIC: Out of Place
COPYRIGHT: I SUBMIT TO THE STANDARD RAYTRACING COMPETITION COPYRIGHT.
JPGFILE: real_her.jpg
RENDERER USED: 

        Self-written raytracer, extended from skeleton code for cse557 at the
University of Washington
       
http://www.cs.washington.edu/education/courses/557/05wi/projects/ray/handout.htm
l
        

TOOLS USED: 

        Modeling scripts in Icon (tree and grass)
        GIMP (for the heron)
        C++ for raytracer
        gcc preprocessor


RENDER TIME: 

        6-7 hours (estimated, with crazy AA settings)


HARDWARE USED: 

        Pentium 3GHz with enough RAM


IMAGE DESCRIPTION: 


A creature from the real world finding itself in a synthetic scene.

The idea for this arose form the disparity between how scenes for a raytracer
are often constructed through a careful and subtle combination of mathematical
functions, and the use of image maps to insert objects/textures from the real
world directly into such a scene.  The use of a bird from the real world
landing inside of a scene built up from mathematical functions pretty much came
directly from there.

I wanted the theme of this image to be rather subtle, rather than to hit the
viewer over the head with the fact that the heron did not belong there, so my
intention was that the heron whould *almost* fit perfectly into the scene, but
not quite.  Thus I put a bit of time into making mathematical foundation of the
rest of the scene non-obvious (though it is still apparent).  In retrospect I
debate weather this was a good idea -- I like the image but the
out-of-placeness of the heron is indeed somewhat subtle, though I suppose there
no a priori reason why it need be blindingly obvious.

In order to somewhat enhance how the heron stands out I created the scene so
that it is the only object in it which has a color that is more blue than red
or green.




DESCRIPTION OF HOW THIS IMAGE WAS CREATED: 


The raytracer used for this image was created from the skeleton code for my
computer graphics class.  As we had to create an image demoing the raytracer, I
decided that I'd also do one that I could submit to this IRTC competition.  We
only had a little over two weeks to write the raytracing code and create the
image, so a lot of the process was pretty rushed.


But first some thanks:

First off, my project partner Jon Froehlich deserves a good deal of credit. 
Although most of his code (of which there was a good deal) does not appear in
this image (I found it easier to write all the things which I'd be using for
it), his splendid antialiasing routine was used in its creation.  The entire
process was also made a good deal smoother than it otherwise would have been by
his good organizational skills and attention to detail in the code in general.

Secondly, the picture of the heron was taken (with permission) from an excellent
photograph by Thomas Michael Corcoran.  his webpage can be found at
http://www.thomasmichaelcorcoran.com/ and the photograph which I used can be
found on the page http://www.thomasmichaelcorcoran.com/2004_05_16_archive.html



Now back to the raytracer.  The skeleton code already handled affine
transformations and ray intersections with simple objects (sphere, cone,
cylinder, box).  Of these, I expected to make good use of cone, but knew that
I'd need to have isosurfaces to handle the landscape.  Accordingly I first
write some code to do ray isosurface intersections.  I used pretty much the
simplest algorithm that came to my mind -- but I looked it up later and it
turns out that it's called `sphere tracing'.

Once the isosurface code seemed to be working, I needed to implement materials. 
The skeleton code rendered every object in a single flat unshaded color, so I
implemented Whitted's illumination model so handle diffuse shading, ambient
shading, and specular highlights as well as reflection and refraction.  This
model gave pretty poor results for objects which were both transparent and
reflective, so I added in povray-style conservation of energy to fix this.  In
order to aid in the creation of more realistic water, I also added an option to
calculate the reflected and refracted values using (perpendicular) Fresnel
reflection.  I also built off of the code for defining functions that was used
in isosurfaces and extended to to allow the specification of three dimensional
textures.  The way it's set up you can (or have to, depending on you view)
specify a texture or a solid color for the diffuse, ambient, specular,
reflective and transmissive material components independently.  I also
specified a function which loads these values from a bitmap, so you can do
image-mapped textures.  The framework would also allow things like AOI or slope
dependent textures, but i didn't use any of these possibilities in the image.

After materials were working, I added in shadows and fog.  In addition to a
global fog I allowed a fog to be specified within an object, in which case it
behaves much like attenuation in povray, though I never got around to making it
work correctly with shadows.  The water in the scene actually has very dark
green fog inside of it, and if you look at the corner where the rock dips into
the water you'll notice it.

A requirement of the project, and also a necessity for this image, was to
implement speedups to handle large numbers of objects.  For this I implemented
a hierarchical bounding box scheme.  It starts by creating a single bounding
box for all of the boundable objects in the scene.  It then divides this box
perpendicular to its longest axis and creates three children: one for objects
which lie entirely less than this division, one for objects which lie entirely
greater than this division, and one for the rest.  These bounding volumes are
then recursively optimized.  In order to support instancing I built the
bounding method to allow unions which would be optimized, but the components of
would be left inside the union.  This allows me to refer to complicated unions
with a single pointer and transformation node -- much the way that as I
understand it povray currently handles meshes.



This describes the basics of the raytracer, so I'll move on to the creation of
the scene.  The tree was the first thing in this image that was created.  To do
so, I wrote a little program in the Icon programming language to help me out. 
This program would generate a tree, and then would allow me to see a rough line
drawing of it for a quick preview.  There's not too much of interest in this
program, as the tree algorithm was pretty much just made in an ad hoc manner. 
The bends in the branches come primarily from gravity and a 1D perlin noise
function, and the code is pretty much tailored to produce exactly what I wanted
for a tree in this image, but doesn't do too much else.  I also wrote a little
script in this program to generate the tufts of grass (which are actually
rather closely approximated by arcs of parabolas).  In order to preview these,
I wrote a plugin for the program which generated povray code.  This allowed me
to work on the tree while the raytracer was not yet in a state to render it. 
Later I of course also wrote an output plugin for the raytracer's input file
format.  In the image, there are actually only 10 tufts of grass, but
differently transformed references to them are automatically placed on the
landscape according to a distribution function defined so that they're placed
relatively well in the context of the rocks and water.  The objects for the
grass and tree themselves consist of just a whole bunch of textured cones.

The function for the landscape is generated by several functions each adding
detail at a different scale.  The holes where the water can be seen come from a
3D smooth noise function, the output of which is modified to give a more
sharply defined hole.  The ridges in the rock are arise from a heavily
turbulated sheared sine wave.  The finer details in the rock are mostly
generated from various modifications of 3D smooth noise.  I found that i could
get quite a bit more realism bu having the degree to which these finer scaled
features where exhibited depend on the value of the ridges and holes,
essentially simulating that softer rocks would weather more.

The texture of the rocks is a layering of an algae texture, and underwater
texture, and a pinkish rock texture.  All of these textures are created from
differently turbulated bands (like povray marble).  In general there's pretty
heavy turbulence applied so that the underlying band structure isn't apparent
and the textures look a bit more swirly.  I also gave the rock very slightly
different hues at different places within the ridges.  In order to increase the
rough sand-papery texture of the rocks, the texture also has a bit of random
noise thrown in -- the idea was to simulate something sort of like povray's
crand graininess.

The water is another isosurface which is essentially the combination of a plane
and a single scale of smooth noise.  The texture is just Fresnel reflecting
with a dark green interior fog.  it's pretty simple, but it worked rather well
I guess.

The heron was taken from a photograph, and then manipulated in GIMP to add
transparency and cut out the heron.  A simple color bmp and a transparency mask
bmp were then generated as used as textures for the emissive and transmissive
components of a texture respectively.  The texture was then placed on a square
in the scene.

In order to make the managing of the scene files and the rendering of teh scene
at various quality setting and objects included, the source files are forst run
through the gcc preprocessor before being rendered.  This let me use
super-handy functions like #ifdef and #include and generally made the scene
creation pretty managable.

