I'm using the Utah Teapot of terrain meshes: Mount Rainier, Washington. The viewer is facing north.
Land-o-Rama now supports four terrain-type textures: grass, forest, rock, and snow. For far distances, Land-o-Rama can use a different forest texture. This allows you to have a forest floor texture for close-up views and a forest texture for distant views. Combined with the three tiled normal-map textures, this version of Land-o-Rama performs 8 texture look-ups per pixel.
A terrain-type texture also use an alpha map to determine roughness. Rough areas have more bump mapping applied to them. So we can make the rock texture look very rough while making the snow texture look very smooth.
The terrain-type map
The terrain types are applied per-vertex by using a terrain-type map. This map has four channels:
- Red channel: Placement of rock textures.
- Green channel: Placement of grass textures.
- Blue channel: Placement of snow textures.
- Alpha channel: Placement of forest textures.
For each pixel, all channels add to 255.
Here is an example of a piece of a terrain-type map:
(To display this image, I replaced the alpha channel with black.)
Towards the right is part of Mount Rainier. The mountain is covered in rocks and snow. Towards the left are low-elevation areas covered in grass and trees. There's a clearcut in the top center of the image; it shows up as rock. The rivers are shown as rock because they are neither vegetation or snow. Eventually, I'll use a SRTM waterbody map to determine river and lake placements.
To build the terrain-type map for a region, Land-o-Rama imports four Landsat channels from that region: 2 (green), 3 (red), 4 (near-IR), and 5 (mid-IR). Land-o-Rama determines vegetation placement by feeding channels 3 and 4 to an algorithm that creates a normalized difference vegetation index (NDVI) map. Land-o-Rama determines snow placement by feeding channels 2 and 5 to a similar algorithm that creates a normalized difference snow index (NDSI) map. These two maps are combined to form the final terrain-type map. Areas that have an NDVI that exceeds a certain value is considered forest instead of grass. Areas that do not have either vegetation or snow is considered rock.
All four channels are then normalized so that they sum to 255.
The vertex shader
The vertex shader hasn't really changed all that much from the last version.
The fragment shader
The fragment shader has been updated significantly. Here is what it does now:
- It samples the normal maps. (It also uses these normal maps as a source of noise.)
- It samples the terrain-type maps.
- It retrieves the terrain type as a four-component vector. (All components should sum to 1.0.)
- It applies noise to the terrain types to make the boundaries between terrain types look better.
- It raises each component of the terrain-type vector by a power of 8. This helps sharpen the boundaries between terrain types. If this was not done, the outlines of areas containing a single terrain type would appear blurry, which generally looks like hell.
- It normalizes the terrain-type vector so that all components sum to 1.0.
- It applies the rock terrain type to areas that have a steep slope. (It uses the z component of the normal to determine slope.)
- It applies the textures according to the weight of the terrain-type vector, performs tangent-space lighting calculations, performs atmospheric calculations, then finally combines all these results together.
Once again, Land-o-Rama took a severe frame-rate hit. On my ancient PC (AMD Athlon 2000 XP, NVidia GeForce FX 5950 Ultra), the frame rate went down from ~24 to ~10 frames per second. I heard that this video card does not do well with pixel shaders. It also performs 8 texture lookups per pixel, so I'm sure that slows things down a lot. Or maybe I just suck making shaders.
Here's some more screenshots:
Mount Rainier, looking east from the ground. There is a big glacier on the mountain's eastern side. On the ground, there's some grass and steep cliffs.
This is Mount Rainier again, this time from the air.
Here's a view of a rocky cliff from somewhere within Yosemite National Park.
This view is within Kokanee Glacier Provincial Park, looking south. The cliff to the left is part of the mountain (I don't know what it's called) that contains the glacier itself.
I'm a little tired of working on Land-o-Rama, so I'm taking a break. Now I'm going to work on libnoise get it to a version 1.0 release. Then after that, who knows? I'd like to try to make a simple run-and-jump platform game. Definitely not a MMORPG :-)