An Introduction to Bump Mapping

metal teapot

 

Non-realtime rendering

For non-realtime rendering applications true bump mapping (a.k.a. displacement mapping) refers to the process of displacing a model’s vertices to add texture to a model’s surface.

original sphere

displacement-mapped

 

Realtime Rendering

For realtime applications such as gaming, bump mapping involves faking the process of making the surface rougher by simply altering the surface normals so that the model reacts to light in a way similar to how it would if a vertex-rich model had instead undergone true bump (displacement) mapping.

normal-mapped (compare to above displacement-mapped version)

Since no vertices are actually being displaced, silhouettes of objects remain as they were before bump mapping.  For example, the silhouette of a sphere would still appear perfectly smooth after bump mapping.  For this reason, it is best to use bump mapping for small scale detail. A more complex hybrid approach can be used to address this shortcoming of normal mapping.

Normal maps from high-polygon objects can be bump-mapped to lower-polygon versions to give models more detail while cutting done significantly on computation.

Both the orange and the alien head are shown with their height map, usually a grayscale image. This must be converted into a normal map. Since each normal is a 3D vector, the normal map is sometimes stored as rgb colors. Rather than deform the surface of the model, which would require more polygons, we calculate a rich normal map to apply to our low polygon model, thus greatly reducing the computation time.

Converting height maps to normal maps

A signed float in the range [-1,1] is mapped to a three-dimensional unsigned byte vector [0,1]. 

<0,0,1> becomes <0.5,0.5,1>

(Normals pointing in the z-direction are light blue.)

 

To convert height data into normal data, one possible solution is to sample each texel of the height map as well as the one above and the one to the right. The corresponding normal is the cross-product of the two vectors (1,0,Hright - Hgiven) and (0,1,Habove- Hgiven).

 

OpenGL lighting equation

Vertex Color = emission+ globalAmbient
+ sum( attenuation * spotlight * [lightAmbient + (max {L.N, 0} * diffuse) + (max {H.N, 0} ^ shininess) * specular])

N - normal, L - incident light vector, V - eye vector, H - vector halfway between L and V.

Coordinate Systems

In addition to the usual chain of matrices leading from object space to clip space and on, we will find it convient to utilize an additional transfomation into tangent space.

Object Space

The light and half-angle vectors must share the same coordinate system with the normals in the normal map or lighting will be performed incorrectly.

Object-Space Mapping

Object-space bump mapping ties your normal map to a specific geometry.  If we take the same object and rotate it, we will need a new normal map.  That is why our brick wall normal map does not produce the correct lighting when applied to the floor which is a rotated version of our original wall. You might say the orientations don't match.

This also applies to situations where we animate the object-space vertices.

Texture-Space Mapping

Light vectors and half-angle vectors are rotated into the normal map’s texture space (tangent space).

Instead of having to rotate every normal in a normal map, you only have to rotate these two vectors.  This makes normal maps more reusable.  With texture-space mapping, one normal map can be used for multiple models in multiple orientations, undergoing animation.

Every vertex may require a distinct rotation matrix, but this is easily assembled and this approach is more computationally efficient than the object-space approach.

Texture tangent space

Tangent-space rotation matrix

Tangent, Binormal, Normal

Multiplying a vector in object space by the TBN matrix yields its transformation into texture tangent space. Transforming our Light and Half-angle vectors into tangent space even with the potential for a different TBN matrix for each vertex is preferrable to transforming an entire normal map.

 

 

Bump-mapping examples

bump mapping a tile floor

http://vimeo.com/4173358

creating a bump map from a photo

http://www.youtube.com/watch?v=RY6OH_o8krw&feature=related

bump-mapping a video game model with GLSL (including downloadable demo)

http://www.fabiensanglard.net/bumpMapping/index.php

bump-mapping demo with Valve's Half-Life 2 Source engine

http://www.youtube.com/watch?v=I3cSBgTONO0

 

References:

http://www.paulsprojects.net/tutorials/simplebump/simplebump.html

http://http.developer.nvidia.com/CgTutorial/cg_tutorial_chapter08.html

http://en.wikipedia.org/wiki/Bump_mapping

http://www.spot3d.com/vray/help/150SP1/tutorials_displacement.htm

http://forums.gametrailers.com/thread/lol--quot-killzone-2-has-bad-t/553311?page=10