Final Project: Lilly Pond
The Making of the Lilly Pond
The initial layout with all diffuse surfaces:
Pure reflection on the water looks pretty bad:
Let's add in some weeds and some sand under water, and make the light source a little more powerful:
Bump mapping on everyting (except the water surface) makes a BIG difference:
Soften things up with an area light:
Use another bump map for water ripples:
First attempt at photon mapping, without taking the color of surfaces off of which photons bounce into account:
The status of my renderings at 3:30pm on the day of the rendering competition (which was scheduled for 3pm to 6pm):
The image still wasn't done at 4:15pm:
By 4:30pm, the small image was done, but I was still waiting on the two large ones:
Final (small) image with low sample sizes, but at least it has everything in it:
Description & InspirationsDescription
I really wanted to do something that represented quiet beauty for this project. This was a really stressful, busy quarter for me, so I wanted to create an image that portrays the tranquility my life had been lacking. On top of that, rendering a scene like this gave me the opportunity to utilize and show off three new techniques that I hadn't tried and/or gotten completely working in previous assignments.
I was particularly impressed by Iman Sadeghi's final project image, "A Butterly, a Water Drop and a High Speed Camera" from CSE 168's 2007 rendering competition. This image has a sense of the quietness and tranquility that I was looking for.
Once I had decided on a lilly pond scene, I looked around
for some actual photos to help guide my image creation.
Surprisingly, I didn't find any that really captured what I
was lookign for. I did, however, come across this computer
rendered screen saver that had the same feel I desired for
Here are some other images I found both beautiful and
- Photon Mapping
Photon mapping is used to calculate irradiance estimates so I can incorporate indirect lighting. In my photon map rendering pass, I shoot out 1 million photons from my single light source. My photon mapping implementation uses Russian Roulette at each photon bounce to determine whether or not to terminate the photon.
- Depth of Field
This feature really gives my image a sense of depth, which makes a huge difference in the quality of realism for the picture. The focal plane is set on the lilly in the image, so the cattails in the foreground and the weeds in the background remain slightly out of focus.
- Bump Mapping
It's amazing what a difference some surface normal imperfections can make in an image! Since most things found in nature are not completely smooth, I revisited the bump mapping code I had written for project 3 (which I had originally implemented incorrectly) and made it work as it should for this project. I ended up using bump mapped surfaces on the three lilly pads, the cattails, the water surface, and the sand beneath the water.
- Fresnel Reflection
This gives the pond surface its realistic water look. Depending on the angle of incidence of a ray hitting the refractive water surface, some portion of light is refracted into the water, while some is reflected off of the water.
- Beer's Law
Beer's Law approximates the amount of light absorption that occurs in refractive surfaces based upon the density of the refractive material. In my image, the water lighting calculations make use of Beer's Law to absorb more light at deeper water levels.
- Area Lights
The single light source in my (final) image is an area light, which gives the image its soft shadows. Without this, the shadows all have very defined, sharp edges.
- HDR Environment Mapping
A high dynamic range environment map is used to give the image a sense of location. I chose to use an image of a forest with fairly subdued lighting (mostly greens, browns, and blues) to maintain the tranquil feel I was going for.
- Procedural Texturing
I created a custom procedurally-textured class for the sand material beneath the water. This class employs both bump-mapping (as mentioned above) and Perlin noise to give it a grainy texture with an illusion of variations in the sand levels.
Behind the scenes, a couple of optimizations are at work to improve the scene build and render time. (Of course, it should be noted that the final image at full resolution still took over 24 hours to render!) My code uses a bounding volume hierarchy that dramatically reduces the amount of time it takes for each traced ray to intersect with the scene. This makes a really big difference when all of the above features are added in to the rendering process. Also, I am using Plucker coordinates instead of Barycentric intersection for my ray-triangle intersection computations, which improves intersection calculation time as well.