Hack 20. Make 3-D Raytraced Terrain Models

Convert digital elevation models into exciting scenes of rendered terrain, using the free raytracer POV-Ray.

The free topographical map data from the USGS makes a fine candidate for creating three-dimensional scenes of territory. The POV-Ray 3-D raytracer allows you to easily import any image for use as a height field in creating a scene with a ground terrain. POV-Ray is available in source code form, and you can get binaries for Linux, OS X, and Windows from http://povray.org/.

POV-Ray has a bit of a reputation for its steep learning curve, but we're not going to do anything terribly complicated with it. We can feed it an image file to use as a height field, with simple parameters that control its display. Once we've done that, we can drape satellite or aerial imagery over the raytraced terrain model, to give it a realistic look. The only really tricky bits are getting the digital elevation models into an image format that POV-Ray likes and orienting the satellite imagery so that it matches the underlying height field.

2.8.1. Getting the Terrain Data

We picked Crater Lake, a lake formed in the caldera of an enormous and ancient volcano in Oregon, to render in our example, because it's a very distinctive-looking terrain feature. If you're in the U.S., you can get data from the USGS Seamless Data Distribution System [Hack #67] at http://seamless.usgs.gov/. We elected to download both the 1" National Elevation Data (NED) as well as the Landsat composite imagery for the area surrounding Crater Lake. Then we drew a box around the lake on the map using the area-download tool, and we were given a pop-up window allowing us to download both files. Make sure that the border of your download selection box stays green!

If you're outside the United States, SRTM data for the whole world at 90m resolution is theoretically available from NASA, as well as ground imagery, including Landsat and MODIS data. The Global Land Cover Facility at http://glcf.umiacs.umd.edu/ is a good place to look for this sort of data, as is the GLOBE Project at http://www.ngdc.noaa.gov/seg/topo/globe.shtml.

Chances are good that your digital elevation model came in the form of a GeoTIFF or, if you got it from the USGS SDDS, a set of Arc/Info Grid files. You'll want to convert this to a 16-bit PNG file, because POV-Ray doesn't understand 16- or 32-bit TIFF files, and 8-bit data is unsuitable for storing most interesting elevation data sets. We can use the gdal_translate utility from GDAL to accomplish this conversion:

$ gdal_translate -ot UInt16 -of PNG -scale 
Input file size is 1596, 1088

For 68893806, substitute the name of the directory into which you unpacked the file from the USGS SDDS service, or the name of your GeoTIFF. gdal_translate is covered in much more detail in [Hack #68] .

If your elevation model happens to be loaded into a GRASS 5.7 location, you can use the r.out.pov command to generate a height field in Targa format, which POV-Ray will accept:

$ r.out.pov map=elevation_model tga=dem.tga


2.8.2. Modeling Terrain With POV-Ray

POV-Ray, which is essentially a program for describing a three-dimensional scene, takes a .pov file as its primary input. The .pov file that we're using to generate a simple 3-D map of our terrain is as follows:

camera {
 location <0, .25, 0>
 look_at <.01, 0, .5>
light_source { <0, 3000, 0> color <1,1,1> } // sunlight
height_field {
 png "crater_lake_dem.png"
 pigment {
 gradient y
 color_map {
 [ 0 color <.25 .25 .25> ]
 [ 1 color <1 1 1> ]
 translate <-0.5, 0, 0>
 scale <1, .1, 1>

All .pov files contain two important elements: a camera, and at least one light source. The camera describes the location and orientation of the scene's viewing point. By default, the scene is one "unit" wide in any direction, which is why all our numbers are fractional. The location and look_at commands place our camera somewhat above ground level, looking ahead and down toward the ground. We define a light_source to be our "sun," 3,000 units directly overheadi.e., very far away. Colors are specified as a vector of red, green, and blue, so <1,1,1> gives us a white light.

Finally, we define the height_field as being based on our digital elevation model, smoothed out (so that the elevation changes aren't jagged), centered on the middle of the model, and then scaled so that the peaks stand out relative to the width and breadth of the elevation model. The coordinate system that POV-Ray uses corresponds to , where x is side to side, z up and down, and y forward and back. Picking a z scale that makes the relative height of the elevation model look correct when rendered appears to be more or less a matter of trial and error.

Finally, the height field in our example is colored with a gradient along the z- (i.e., vertical) axis that runs from dark gray at the lowest elevation to white at the highest. We render this .pov file with the following POV-Ray command:

$ povray +A +W800 +H600 +Icrater_lake.pov +Ocrater_lake.png

The +W and +H options specify the image width and height, and +A turns anti-aliasing on, which makes the rendering look nicer but take longer. We get a grayscale model of the terrain, as illustrated in Figure 2-19. Not bad for a first try.

Figure 2-19. A grayscale rendering of Crater Lake

To save time when experimenting with POV-Ray settings, try leaving anti-aliasing turned off. This will speed up rendering time by at least a factor of twoand then, when you've got your .pov file tweaked just the way you want it, you can do one more rendering pass with anti-aliasing turned on.


2.8.3. Color Your Terrain with an Image Map

POV-Ray also offers an image_map function in POV-Ray, which allows us to specify an image with which to color each value in the height field represented by your elevation raster layer. You can use the color values in the terrain image itself for a basic grayscale height-shaded effect. With your favorite graphics program, you can adjust the palette in the image to produce a more colorful effect, in a similar fashion as that described in [Hack #32].

The excellent terraform, available for GNOME on Linux and Mac OS X, has a selection of color maps that you can apply over your image and save into a .png for POV-Ray's consumption. Visualize your terrain image as a heat map, a desert, or a strange radioactive alien wasteland. If you haven't played with terraform, start with the pointers in [Hack #100] .

Load your scene into terraform and select View images/ent/U2192.GIF border=0> Colormap images/ent/U2192.GIF border=0> Wasteland, for example. From the View Type menu, .png or VRML formor export the scene as a 3-D plane to POV-Ray, or as a 2D bitmap to the GIMP. You can add the PNGs to your .pov file as color maps. terraform is a wonderfully flexible program!

If you have another image containing a map in the same projection with the same extents as your DEM, you should be able to drape it over the top of your terrain model. We obtained a composite Landsat image of Crater Lake in GeoTIFF format from the USGS SDDS at the same time that we downloaded the NED elevation model that we used earlier. Since POV-Ray will read 24-bit TIFF images, and our Landsat GeoTIFF has the same projection and extents as our DEM, we can just drop it right into our .pov file by replacing the pigment section of the height_field entry with the following:

 pigment {
 image_map {
 tiff "75178917.tif"
 interpolate 2
 rotate <90, 0, 0>

The tiff instruction points to our GeoTIFF file. If our imagery weren't in 24-bit TIFF format, we could have used gdal_translate to convert it to PNG format, and then put a png command in our image_map instead. The interpolate command improves the look of the rendering, and the once command tells POV-Ray not to tile the image. Finally, because POV-Ray expects the image_map in a different orientation than the one we are providing, we rotate the whole pigment by 90 degrees in the x-axis to line it up with the underlying DEM.

To improve the highlights in the Landsat composite, we also add an additional light source to the top of our file, like so:

light_source { <100, 500, 10000> color <1,1,1> } // ambient light

Also, we want a realistic background for our terrain model, so we render a clear blue sky in the background, by adding the following sky_sphere section to the end of our .pov file:

sky_sphere {
 pigment {
 gradient y
 color_map {
 [ 0.2 color <.5 .75 1> ]
 [ 1.0 color <0 0 .5> ]
 scale 2
 translate -1

Finally, we rerun the rendering process as before. This time, it takes about 90 seconds on our machine, but the result, as shown in Figure 2-20, looks pretty fantastic! The important thing is that the elevation model and the image map need to have the same extents and be more or less in the same projection in order to line up. If they don't, you can use gdalwarp to trim and/or reproject the elevation model to match the image map, so that they do line up. Again, gdalwarp is covered in more detail in [Hack #68] .

Figure 2-20. A raytraced rendering of Crater Lake, colored with Landsat imagery


2.8.4. Rendering Hand-Drawn Maps in 3-D

Of course, you don't have to drape satellite imagery over a digital elevation model. In particular, digital raster graphics (DRGs) of the USGS's hand-drawn topographic maps make great image maps for 3-D terrain. Figure 2-21 shows an example of a USGS DRG of the 7.5-minute El Capitan quadrangle draped over the matching 10-meter USGS DEM, rendered from just above the valley floor, looking towards El Capitan.

Figure 2-21. A raytracing of Yosemite Valley, looking towards El Capitan

We obtained the DRG from the California Spatial Information Library at http://gis.ca.gov/ and got the DEM for the same quadrangle from the free download service at http://gisdatadepot.com/. Of course, gdal_translate works just as well on the SDTS-format DEMs provided by gisdatadepot.com as it does on your standard GeoTIFF. We then copied the .pov file from our rendering of Crater Lake and changed the camera location and angle so that it looks eastward from the valley bottom. Finally, we set the scale to <1, .2, 1> to emphasize the valley's contours.

In general, tourist maps, and even many online satellite-derived, vector-based maps such as MapQuest's, don't exactly correspond to the real topography of the surfacethe area of a park there, the width of a street here, the shape of a mall elsewhere. Older maps may have measuring discrepancies, built up over the years, or bits of the topography may have genuinely changed since they were drawn. The process of taking an old or evocative map and stretching it so that it matches up with a more accurate base model is sometimes referred to as rubbersheeting, and it's a technique that David Rumsey uses to overlay nineteenth century maps over scenic terrain [Hack #23]


. See [Hack #33] for more details about augmenting the spatial accuracy of non-GIS maps.

As a final note, POV-Ray can even be used to render terrain found in the Solar System! This very possibility is explored in [Hack #34] .

But wait, there's more! POV-Ray can also generate successive frames of "fly-through" sequences, allowing you to pan and zoom a camera through your rendered terrain. An open source video encoder, such as mencoder, can then be used to stitch these frames together into sometimes breathtaking short animated clips. See http://mappinghacks.com/projects/povray/ for further exploration of this idea.

Mapping Your Life

Mapping Your Neighborhood

Mapping Your World

Mapping (on) the Web

Mapping with Gadgets

Mapping on Your Desktop

Names and Places

Building the Geospatial Web

Mapping with Other People

Mapping Hacks
Mapping Hacks: Tips & Tools for Electronic Cartography
ISBN: 0596007035
EAN: 2147483647
Year: 2004
Pages: 172

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net