CS 6620 Advanced Computer Graphics II - Assignment 4
Zach Gildersleeve
February 14, 2007
Required Image
Here is the required image, as produced by the program. It took on average 5.6 seconds to render.
The heightfield is constructed of a representation of (1.2*sin(x*15)*sin(y*30)/(r2*sqrt(r2)+0.47)) + 2, where r2 = 24*(x*x+y*y), and the return value is clamped at the edges.
Code Listing
The code for this image can be found here.
Design Choices
This assignment builds on the previous assignment. The class HeighField follows the algorithm presented in class. The heightfield file is read in, and a bounding box is created from using two Points that represent the diagonal axis through the bounding box, similar to what was implemented in Box. A quick intersection test is preformed using that bounding box and recycled code from Box. If the ray is found to intersect with the bounding box, the lattice coordinates of the hit point are found (in "Box Space"). Depending the on the ray's orientation, the ray marching index is determined for the x and y direction, and likewise the change in the ray's t value for each step. The far edges of the current cell are determined in both "Box Space" and ray t values. At this point the ray is marched along, and the cell intersection location is computed. Once the ray intersection with the cell is round, the cell is rendered using a bilinear intersection method. I implemented the Scratchpad in the HitRecord class to store values for the normal. In this instance, the normal can be reconstructed with just knowledge of the cell position in "Box Space."
Creative Image
For my creative image, my first intention was to include a heightmap from an elevation dataset, but I experienced difficulty working with the datasets, or at least getting a dataset to work with my raytracer without creating a separate class to handle each dataset. Instead, I decided to generate a fractal terrain heightmap, using a shortcut diamond-square method to recursively subdivide the array storing the heighfield data. The diamond square is a two step method that subdivides the terrain first into squares, averages the corners and assigns the squares center point to the average plus a random amount. The square's diagonals plus the new center point can be divided into diamonds, a similar averaging procedure preformed, and the center of the diamond thus creates smaller squares. I only had time to implement the square part, and even so results were mixed. As I discovered several hours into the process, this process only perturbs each point. Thus, doing a recursion level of 4 steps results in a series of impulses across the heightfield, and the heighfield process does not necessarily interpolate across the impulse values to create a smooth surface. A higher level of recursion simply creates a denser field of impulses, which creates some interesting behavior, but is not what I was expecting. This is evident in the image below. There is the variation that I would expect with fractal terrain, but the impulse behavior is distracting.
What is needed is a bilinear interpolation method to keep the heighfield correct across each recursion step by interpolating the field from impulse to impulse, or another modeling technique such as a triangle tessellation or spline modeling to allow for this. I was able to fake this by averaging out the unaffected (non-impulse) values, which resulted in a smooth, rolling landscape. I populated this environment with some Triangle trees to complete my creative image. The shape of the underlying heighfield is best illustrated by the shadows from the trees, which follow the curve of the landscape. These image took around 1.5 - 2 minutes to render given the number of triangles in the forest.
Extra Credit
I spent the time working on the creative image rather than the extra credit. Seeing as how the QAEB algorithm is one means to accomplish what I spent hours on trying to derive, perhaps I should have completed this first, and then gone about my creative image. I did find it interesting that Ken Musgrave is currently a realtor in West Virginia, or as he calls it, real real estate.
Additional Comments
The required image took me about 15 hours, and was fairly straightforward given the algorithm presented in class. Most of the time was spend on the bilinear patch code, and troubleshooting the scale factor necessary to not clip the top of the sine curves off at the bounding box. The creative image took about 15 hours as well. This time included exploring different elevation datasets such as DEM, NED, and TIFF, attempting to perform byte swapping and reworking the HeighField class to work with these datasets, and about 8 hours exploring the fractal terrain parameters.