CS 348B - Computer Graphics: Image Synthesis Techniques
HW2 - Heightfield intersection
Assigned Thursday, April 11. Due Tuesday, April 23.
For this assignment, you will improve lrt's support for rendering terrain - landscapes and seascapes.
Terrain is often represented as an elevation map, or what we will call a heightfield: a table indicating the height of a surface above each point of a uniform 2D grid. In other words, we are tabulating the values of a height function z(x,y) in a 2D array. As you know from Section 3.9 of the lrt book, rudimentary support for heightfields is already provided - lrt can parse them, but it just turns them into triangle meshes for rendering.
Heightfields have a very orderly structure, which is ignored in simply turning them into triangle meshes. Your assignment is to apply techniques like those used for acceleration structures to develop a fast intersection routine for heightfields. An efficient solution will be substantially faster than the default implementation.
First you need to retrieve a slightly updated version of lrt from the class directory. The new version corrects a bug and features some reorganization of the heightfield code to make it easier to work with - two new files, heightfield.h and heightfield.cc, have been pulled out from shapes.cc. You can delete your current copy of lrt and replace it with the new distribution. As before,
- Copy /usr/class/cs348b/files/lrt.tar.gz to your working directory.
- Type gunzip lrt.tar.gz in the directory with lrt.tar.gz. The result is a file named lrt.tar.
- Type tar xvf lrt.tar. This will extract the files you need into a new directory called lrt.
- Compile lrt. The Makefile provided works for the machines in the Sweet Hall lab.
Note that we can't offer much support for other development environments (e.g. Visual C++). However, please let us know if you have success on other platforms - we'd like to share any tips with the class, and with the lrt authors!
For this project, there are several new scene files available in the class directory. When given multiple files on the command line, lrt reads and parses them one after another, as if they were one long file. Three RIB files are provided to start this assignment:
You should copy these three files from /usr/class/cs348b/rib/ to your working directory.
Type lrt hw2.rib sea1.rib land1.rib to begin rendering. This will generate hw2.tiff, a simple outdoor scene.
- hw2.rib sets up the camera and a texture mapped cylinder representing the sky.
- sea1.rib defines a heightfield for the surface of the "water" - a colored reflective material.
- land1.rib defines a heightfield for the surface of the ground - a matte brown material.
You may find the rendered image seems a bit gray or dimly lit. Later in the quarter you'll experiment with adding tone mapping and fancier exposure control to lrt. For now, however, you may wish to fine-tune the color-balance of your images in a post-process. A simple image editing tool, xv, is available in the class bin/ directory. Within xv, pressing 'e' will bring up a menu of color manipulation tools. If you click the 'Norm' button (in the button palette second from the bottom in the leftmost pane), the image will look somewhat nicer.
The heightfields used for the land and water here are only 64x64 - as you can see, the low resolution is obvious in the resulting images. The "water" surface doesn't look very good with polygonal facets! After you have written a fast heightfield intersection routine, you'll be able to render much higher resolution heightfields, such as 1000x1000. To see examples of what is possible with higher resolution, take a look at the entry on rendering ocean scenes from the 348b rendering contest last Spring. In addition to having a fast heightfield intersection routine, the authors also performed Phong interpolation of the normals for each triangle to make the water surface appear smooth.
As encouragement, there is a 1000x1000 ocean heightfield available in the class directory: /usr/class/cs348b/rib/sea1000.rib. There are also a number of other sky textures to choose from in the /usr/class/cs348b/textures/ directory.
To complete this project, you'll just need to modify the files heightfield.h and heightfield.cc. Rather than refining a heightfield to a triangle mesh, you should provide an Intersect routine that will intersect rays directly with the heightfield. You should put some thought into how to do this efficiently. The lectures on acceleration structures like grids and kd-trees should suggest good approaches. Note that the heightfield data is already basically in the form of a 2D uniform grid - this should be helpful for whatever method you decide to implement.
Of course, your method should be robust - be sure it can work from a variety of viewpoints (and for a variety of different heightfields).
Once you've got intersection working, you can add some additional features. In particular, you should:
- Have your heightfield intersection return sensible values for the u and v coordinates, so that you can texture map heightfields in a natural way.
- Perform Phong interpolation of the normals across each heightfield triangle, as in the ocean scenes project.
Turn in your finished homework using the cs348b submit script:
/usr/class/cs348b/bin/submit hw1 dir
Make sure you hand in all your source code, a Makefile, and a README
file. The README should contain instructions for compiling and
running your code, and a description of anything non-intuitive you've
done. Please do not submit any executables or object (.o) files. We'll
be building your submissions ourselves, and those just take up space.
This homework, and all subsequent programming assignments, will be
graded according to the following system:
0 - Little or no work was done
* - Significant effort was put into the assignment, but not everything
** - The algorithm you implemented was functionally complete;
it passed all of our tests.
*** - The algorithm was more than twice as fast as the original, basic
Copyright © 2002 Pat Hanrahan