Gamasutra: The Art & Business of Making Gamesspacer
"Ups and Downs" of Bump Mapping with DirectX 6
View All     RSS
August 21, 2018
arrowPress Releases
August 21, 2018
Games Press
View All     RSS
  • Editor-In-Chief:
    Kris Graft
  • Editor:
    Alex Wawro
  • Contributors:
    Chris Kerr
    Alissa McAloon
    Emma Kidwell
    Bryant Francis
    Katherine Cross
  • Advertising:
    Libby Kruse

If you enjoy reading this site, you might also want to check out these UBM Tech sites:


"Ups and Downs" of Bump Mapping with DirectX 6

June 4, 1999 Article Start Previous Page 2 of 7 Next

The Embossing Technique

The embossing technique is a good way to add detail to your scenes without necessarily upping your geometry requirements. Though it can't be used to do as much as the DirectX 6 bump mapping method, it has the advantage that it works on the bulk of today’s 3D hardware.

Embossing uses a height map to add the appearance of protuberance to the surface. This is done by brightening and darkening the surface in different areas to make it look like the lighting in the scene is adding highlights and shadows (see Figure 1). While there are numerous ways to achieve this effect, one that works on most hardware (that is, on hardware that only supports single textures and basic alpha blending) involves doing three passes.

Here’s how this method works. First you create a height map texture. This could be a bitmap generated by an artist, of say, rivets, or in some cases it could be generated algorithmically (for example, with a brick wall texture, you could just assume places of a very different color are mortar, and thus depressions). This height map should be scaled or clamped to fit within a 0-0.5 range (where 1.0 is full intensity, or 255,255,255 in the case of a 24-bit texture). (Of course, the heightmap could be authored from scratch in this range.) Make a copy of the height map, equal to 0.5 minus the height map value – in other words, an inverse of the height map. This removes the need for a signed add, which a lot of 3D hardware doesn’t support. (This could also be authored ahead of time, but would double texture storage requirements).

On the first pass, your engine should render the polygon using the height map as the texture (see figure 1A). Shift the UV texture coordinates of the "negative height map" so that the texture faces towards the light source (figure 1B), according to the angle between the light vector and the vertex normal. For a directional light, the shift is the same for the whole polygon, and you would use the polygon normal. For a point or spot light, you would do a different shift for each vertex. The degree to which a height map should be shifted depends on the type of texture. If your height map contains sharp slopes, then over shifting can ruin the effect. If the slopes in the height map are gentle, then undershifting will hide the effect.

The second pass requires that you shift the triangle’s UV coordinates toward toward the light source, and then render the triangle using the "negative height map" (figure 1B) as the texture (the inverse bump map), using additive blending. At this point the frame buffer will contain values from 0 to 1, where pixels with values of 0.5 represents no bump, pixels with values less than 0.5 represent depressions in the surface, and pixels with a value of greater than 0.5 are sections on the surface that are raised toward the light. The result should be a grey texture with shadows and highlights (figure 1C).

On the third pass, you render the polygon with the object’s base texture, using modulate 2X mode. The 2X mode is used to effectively "cancel out" the 0.5 base value from the second pass, because the "flat" areas of the triangle contain a 0.5 value now (half of full intensity), so using a simple modulate would darken the triangle. The 2X cancels this out, resulting in full intensity for 'flat' areas, and bumped areas tend towards white or black, depending on location (see figure 1E).Likewise, when the values in the frame buffer from 0 to 0.5 tend toward 0, and values from 0.5 to 1 tend toward saturation.

Figure 1 – Embossing illustration.
The following images illustrate the embossing
technique, in the order it is done.

Figure 1A - Bump map

Figure 1B - Inverse bump map (0.5 - bump map)

Figure 1C - Bump map + shifted inverse bump map.

Figure 1D - The object's base texture.

Figure 1E - Bump map + shifted, inverse bump map,
modulated with the base texture, and doubled.

The amount to shift the UV coordinates during the second pass depends on your application, and there is no hard rule for determining how far the texture should be shifted. Height map textures with sharp rises will cause artifacts if they are overshifted. On the other hand, undershifting will result in hiding the effect in places where the height map textures have soft edges on them. The proper amount to shift the height map depend on your content and how dramatic or subtle you want the effect to be.

The shift of the UV coordinates can be done once per triangle for a directional or distant point light. In the case of a point-light source (a light relatively close to the triangle being rendered), you may wish to calculate the shift per vertex, to get a shift that varies across the face of the triangle. (The sample application allows you to toggle between the two)

To improve the performance of this technique, embossing can be accomplished using two passes on most multi-texture hardware. Better yet, embossing in one pass can be accomplished on several of the newer 3D cards (like the 3dfx Voodoo2, ATI Rage 128, 3D Labs Permedia3, Matrox G-400, and Nvidia Riva TNT), but unfortunately the implementation varies from card to card, and results aren’t always the same, either. If you are willing to implement the different code paths, though, the added performance may be worth it.

While the embossing method works well and it’s easy to implement, it also has a number of limitations. It is merely a lighting trick, so it does not affect things like reflection and environment maps. Also, it only works under monochrome lighting (although it may be possible using a fourth pass to change the light color). Finally, the programmer has to ensure that the inverse bump map is not shifted too far from its original position, as the embossing effect can be ruined, and it starts to look more like someone cut shapes out of the triangle with scissors

Listing 1 contains code for implementing the embossing method of bump mapping under DirectX 6. (The downloadable "Emboss" sample application also explains how to implement the same effect in two passes on multi-texture hardware. I have left the many different single pass methods as an exercise for the reader, but several of the different card vendors have sample implementations on their developer websites.

Article Start Previous Page 2 of 7 Next

Related Jobs

Mimic Technologies
Mimic Technologies — Orlando, Florida, United States

Senior Lead Software Engineer
Game Closure
Game Closure — Mountain View, California, United States

System Software Engineer
Against Gravity - makers of Rec Room
Against Gravity - makers of Rec Room — Seattle, Washington, United States

Server Engineer - Rec Room (VR)
Bohemia Interactive
Bohemia Interactive — Mníšek pod Brdy, Czech Republic

Game Programmer

Loading Comments

loader image