Goal: In this lab, you will render a 3D terrain with objects that interact with it. The terrain is given as a heightmap image.
Since this is the last lab, it is more flexible than usual. There are several interesting non-mandatory tasks at the end.
|
Lab files:
You will also need files from earlier labs (textures, helpers). The makefile is similar to old ones.
The initial lab shell loads the small terrain "terrain-44.tga" and
draws it with texture. There is, however, no light and no normal
vectors.
To compile this assignment, perform make lab4-1 on the command line.
Run the assignment by performing ./lab4-1.
Questions:
|
Goal: To move around a large heightmap.
Copy lab4-1.c to lab4-2.c. Make this section's changes to lab4-2.c.
Try loading one of the larger heightmaps. You may need to scale the map differently.
Use your code from earlier labs for placing the
camera so you can move around it nicely. (If your camera movement is good, this is easy.)
Questions:
|
Goal: To make the heightmap look better by using lighting.
Copy lab4-2.c to lab4-3.c. Make this section's changes to lab4-3.c.
Lighting should be familiar to you by now. Generate a normal vector for every vertex in the surface to make a decent lighting of the scene.
Apply lighting on the terrain by using a shader from earlier labs.
The triangle positions must be used for finding the normal vector. You can choose from two methods:
1) High precision version. For a vertex, calculate normal vectors
for all neighbor triangles. Then calulate a weighted average of these.
For maximum precision, this should depend on the angle of the triangle.
This is fairly easy for a terrain since the angle, projected on Y, is
always 45 or 90 degrees.
2) Good, fast approximation. Pick three neighbor vertices, on all sides of the vertex, and use these three for calculating a normal vector.
In all cases, you must check for edges and use some special case
there. If you are significantly behind schedule, it is OK to just skip
these normals, leaving them unchanged. (You don't do that in "real
life" though, where the terrain is often a patch out of many.)
Questions:
|
Goal: To find the height of the heightmap for any given point and place objects in the scene using that information
Copy lab4-3.c to lab4-4.c. Make this section's changes to lab4-4.c.
Your height map is drawn as a set of triangles. For a given point (x, z), find the y value.
This is done in three steps:
1) Calculate what quad the point falls into.
2) The quad is built from two triangles. Figure out which one to use.
3) Calculate the height value. There are several ways to do it.
You can interpolate over the surface, or you can use the plane
equation.
Using this function, place objects on the surface. You may use anything but the models "groundsphere.obj" and "octagon.obj" can be nice.
groundsphere.objThe object should slide smoothly along the surface without jumps, and must not go between exact vertices but interpolate nicely. (Note: Interpolate on the CPU and use the height for translating the object. This is not a shader interpolation problem.) You can use the low-res terrain for testing; it can be pretty revealing.
Hint: When debugging, it can be worthwhile to return to the small
terrain, possibly scaling it up so it is easy to see what happens.
Otherwise you may have so many polygons that you can't really tell why
the object moves in a certain way.
You only need to check height for the bottom point of the object.
This means that it might overlap the surface in other places. We accept
this error for now.
Questions:
|
If you get here quickly, well within the lab time, I expect you to make two of these. If you are short of time, you only have to do one.
Remember that some nice features can be part of your project even if you don't finish them here, in case there are several features below that you feel are desirable (and there surely are).
Copy lab4-4.c to lab4-5.c. Make this section's changes to lab4-5.c.
Goal: To make the terrain look even nicer through multitexturing.
Using at least two textures and a shader, blend the textures in some appropriate way (height, slope) to make the terrain more realistic, interesting and/or beautiful.
Questions:
|
Goal: To put many objects in the "world"
Introduce many objects, either many of the same or different objects. In any case, you may use spheres for collision detection. Handle collisions between the objects and between all objects and the surface.
Questions:
|
Goal: To measure the slope of the terrain and apply it on objects
Every polygon has a slope, that is its normal vector. Use that information to draw objects that are appropriately tilted to match the slope. Test using the low-res terrain.
Questions:
|
Goal: To handle a part of the terrain separately to make a lake
One of the terrains, "fft-terrain.ppm", has a big flat area in the middle of the map. This area could be considered a "lake". Identify the appropriate "water surface" polygons and paint them blue.
Luxury variants (teasers for advanced students, but generally more interesting for your projects):
Questions:
|
Goal: To move the camera over the terrain
Adapt your camera movement to make the camera move over the terrain without intersecting it.
Questions:
|
Goal: To optimize model drawing by only drawing them if visible
In large worlds, models will often be outside the viewing frustum. Then drawing can be speeded up significantly by excluded out-of-view models. Several ways to handle this are outlined in the book.
For doing this, you need to find normal vectors for all frustum planes. You can safely forget the near plane, though.
To use this for a model you should use a bounding sphere.
Questions:
|
Goal: To optimize terrain drawing by only drawing visible parts
When using large terrains, large parts of the terrain will often be outside the viewing frustum. Then drawing can be speeded up significantly by excluded out-of-view polygons. Several ways to handle this are outlined in the book.
To use this for a terrain, you must split the terrain into at least four sections, or (better) extend the terrain to a much bigger world. The frustum culling will limit drawing to at most four sections (granted that your frustum isn't too long).
For the lab, note that the provided terrain is wrap-around so you can just reuse it for additional sections.
Questions:
|
That concludes lab 4. We hope that this gives you a start in programming geometry yourself as needed, and maybe gives you tools and ideas to use in your projects.