DirectX 6 Environment-Map Bump Mapping
DirectX implements bump mapping using a technique best described as "environment-map bump mapping". This method can only be used on systems with hardware that specifically supports it. (See Table 2 for information regarding which DirectX caps bits indicate support under Direct3D). In the coming months, there will be a few 3D accelerator cards that support this method of bump mapping in hardware. Those announced include the Matrox G-400 and the 3D Labs Permedia3, and it is likely that many others will follow. The wide variety of effects it can achieve are impressive. We’ll get into it some of those later, but first, let’s see how the feature works and how it is used.
In DirectX 6, bump mapping is implemented using two textures (not including the object’s base texture). The first is a bump map which contains slope information (you can think of it as a height differential map), rather than height information, as is the case with the embossing method. (The bump map is generated by comparing adjacent texels in the height map). Hardware that supports DirectX 6 bump mapping uses these values to perturb the texel coordinates used in the lookup into a second texture (as opposed to using the data to alter the polygon’s normals). The second texture is an environment map, which is rendered onto the original polygon using these perturbed UV coordinates. Figure 2B shows what this looks like, where the environment map in this case is the scene above the water, render to a texture).
By making the environment map a radial gradient lightmap (something like you'd get holding the airbrush tool in a paint package in one place and holding down the mouse button for a second), we can achieve the same effect as the earlier embossing technique. Additionally, we are not limited to a single light source, nor to monochrome lighting.
The technique is as follows. First, set up D3Dtexture2 surfaces for the object’s base texture and the environment map, and fill them with bitmap data as usual. Next, set up a D3Dtexture2 for the bump map, but specify a couple additional caps bits during the DirectDraw surface creation. If necessary, create a height differential map from a height map. (I say "if necessary" because the bump map could be stored this way already, but if a height map is used, it needs to be modified.) Creating a height differential map from a height map simply involves stepping through the bitmap, and comparing neighboring pixels to get the slope, as shown in Listing 2. When you have the height differential map created, assign it to the surface you want to be bump mapped . Then you should set up the Direct3D texture cascade for the three textures and for the bump mapping-related D3DtextureStageState variables. These would be:
Stage 0 – Set texture to base texture (as usual)
Stage 1 - Set texture to bump map
Stage 2 – Set texture to environment map
For Stage 1, The additional render state values that can optionally be set up are:
The only thing left to do in each frame is render the triangles. Listing 2 is a code snippet demonstrating this technique.