In this section, we go through a few ideas that could extend the texture mapping and lighting you created in this chapter. We've really just scratched the surface with, well, surfaces. With the shaded surfaces, you applied shading only to the texture, but you could also do all sorts of other effects, including effects created on the fly. For example, you could apply a "burn" effect if the player uses a flame thrower on the wall, or add an occasional surface "crack" to break up texture monotony, or show robot blast marks on the floor when you destroy a robot.
Another lighting trick is to have objects farther away appear darker than those close up so the amount of light you see diminishes with distance. This technique, called depth cueing, was popularized by games such as Doom and was a common effect on the Nintendo 64. In games such as Doom, the textures fade to black with distance, but there's really no reason to restrict the depth cuing to black. Several games for Nintendo 64 created a "fog" effect, with everything fading to a grayish hue.
In the next chapter, "3D Objects," you'll create individual objects that can roam around your 3D world. Sometimes, however, it's difficult to tell where an object is in relation to the floor, and an object can sometimes look like it is floating. To fix this visual quirk, a common technique is to draw a circular, fake shadow underneath the object. It's a "fake" shadow because it does not represent the object's shape (you won't see a shade for a robot's extended arm, for example), but it's a quick way to give a visual cue on the location of the objects.
With your surfaces, it's a big of an overkill to create a large surface for a polygon that is very far away. Really, it would make more sense if polygons that are far away from the camera have surfaces that are smaller sizes. This technique is called MIP mapping. For the curious, MIP is an acronym for Multum in Parvum, which is Latin for "many in one." Far polygons have smaller surfaces, and sas the surface gets closer to the camera, larger surfaces are created, if necessary. This technique can save a lot of memory and makes surfaces farther from the camera look smoother.
When you run the demos in this chapter, you'll notice that when you're very close to a texture, the texels look blocky. Likewise, when you're far from a texture, slight artifacts creep up because not every texel in the surface is drawn to the screen. This is especially noticeable if the textures have sharp lines. Bilinear interpolation eases both of these issues. Just as you interpolated between adjacent different values in the shade map, you can interpolate between adjacent texels in the texture, smoothing it out so that close-up textures don't look as blocky and so that textures farther away don't have as many artifacts. I created the textures in this tutorial to have no or very few sharp lines, so this effect of seeing artifacts when you're far away from a texture is minimized, even though bilinear interpolation would still look nicer. If you use something like the "test pattern" texture, you'll notice all sorts of strange-looking artifacts. Bilinear interpolation would greatly help to eliminate those artifacts.
Trilinear interpolation is basically the combination of bilinear interpolation and MIP mapping. Instead of just interpolating between adjacent texels in a texture, this technique interpolates between adjacent MIP maps (one MIP map farther away from the camera and one MIP map closer). This eliminates any noticeable change when you move from one MIP map to another because two MIP maps are used and interpolated between.
Normal Maps and Depth Maps
Some of the textures used in this chapter had a bit of "fake" lighting built right into the texture to give the textures a bit of depth, like rocks jutting out with light and shadow around the rock edges. Of course, this fake lighting isn't accurate because it doesn't take into consideration the lighting of the surrounding environment. The "fake" lighting could assume there is a light source in the upper-left corner, but in the environment, the light source could come from a different direction. Some 3D accelerator cards can use normal maps and depth maps to create textures that respect the surrounding lighting. Instead of a texture map, you'll have three maps: a color map (with no lighting in it), a depth map (to specify the "depth" of each pixel in the color map), and a normal map (to specify the normal vector of each pixel in the color map). Using the color, height, and normal vector, the correct lighting for each pixel can be calculated, resulting in a texture that respects the lighting of the surrounding environment. Even though this is an expensive process, some 3D accelerated cards can combine these three maps quickly in real time.
Other Types of Lights
One last thing to mention is light sources. The only light source you used here was point lights that radiate in all directions equally, like the sun. To extend the lighting architecture, it would be great to add colored lights, cone lights (lights that radiate in a cone rather than in all directions), or an area light, which might come from a rectangular source and radiate out like a pyramid. Also, although you can't see it in this demo, the lights can actually pass though a polygon to hit another polygon on the other side. It would be great to eliminate this by making sure that any light ray that hits a surface doesn't hit any other surface first.