Anyone who has spent some time 3D modeling in any of the popular modeling packages has probably already been exposed to bump mapping. In fact, artists not constrained by the limits of real-time 3D game engines use bump mapping quite extensively to add height to rivets, texture to brick walls, and otherwise add nooks to their crannies and crannies to their nooks.
Recent advances in consumer hardware and software bring us to the point where we can now begin to implement bump mapping in DirectX-based games. Coupled with procedural texturing techniques, AGP texturing, and today’s powerful processors, some very impressive effects are possible.
You may be asking, "I’ve never used a modeling package – what is bump mapping?" First, I should explain that the way bump mapping is implemented under DirectX 6 is not what purists would call "real" bump mapping. If you asked Jim Blinn to tell you about bump mapping (and he would know, as he invented it), he would likely tell you it’s different than what I’m about to present. Blinn would tell you that bump mapping adds surface detail (bumpiness) to objects in 3D scenes, without adding more geometry than already exists. It does so by varying the lighting of each pixel according to values in a bump map texture. As each pixel of a triangle is rendered, a lookup is done into a texture depicting the surface relief (a.k.a. the bump map). The values in the bump map are then used to perturb the normals for that pixel. The new bumped-and-wiggled normal is then used during the subsequent color calculation, and the end result is a flat surface which looks like it has bumps or depressions in it.
So, this sounds great to you, right? Now you want to know how to code it up in DirectX 6. Well, you can’t implement textbook bump mapping in games. At least not as Blinn or other graphics gurus would have you do it. There are a couple reasons for this. First, today’s 3D hardware doesn’t perform a per-pixel lighting calculation. Instead, it performs Gouraud shading, where colors are interpolated from values calculated at the vertex level. Second, even if the hardware did perform bump mapping, you still couldn’t feed the API the normals and lighting information. It’s sort of a chicken-and-egg situation: if the hardware doesn’t perform the lighting (or even know where the lights are), then it can’t use a bump map to modify the lighting.
Since we can’t do "textbook" bump mapping under DirectX 6 with today’s hardware, another method is needed. As it turns out, there are two. The first method uses multi-texture or multi-pass rendering to achieve an embossed effect using a bump map. There’s a second, more versatile, method of performing bump mapping under DirectX, called environment-map bump mapping, and it is supported by DirectX 6.