Delux mapping

1. What

The bumpmapping commonly used in real time applications requires a pass per light source in the scene (In the best case).  This works well as long as there aren't much light sources in the scene and you can model the light in the scene using directional or point lights.
This is often the case for dark indoor areas with low ambient levels, but outdoor areas require a lot of point light sources to simulate the "radiosity" in those scenes.
At first we used normal lightmapping to model the ambient light in Tenebrae.  This works fine but the disadvantage is that art that looks good with per pixel lighting looks flat and boring since there is no hard coded shading in them.  Adding hard coded shading on the other hand takes away some of the bumpmapping quality.
Or new solution is to use bumpmapping on the ambient lighting too. This is what we call delux mapping.

Hard coded lighting Flat, for use with normal map

2. The Idea

Delux mapping works by adding an extra precalculated map (besides the lightmap) to the level file.  Just like the light map this map has unique information for every surface in the world.  Instead of storing a color it stores an (range compressed) vector that points to the incident light on that surface.
When you render the ambient pass of the surface instead of modulating the lightmap with the color map we use the following equation
((delux . normalmap ) * 0.5 + 0.5) * lightmap * color

 No delux  With delux  Delux map

3. How to calculate the delux maps

Delux maps are calculated at the same time the light maps are calculated.  For every light that shines on the luxel we update the delux map.  This is done by averaging the tolight vector with a scale factor that is the brightness of the light's contribution on that luxel.
This light doesn't have to come from an actual light source.  It can be light bounced back into the scene by the walls, a surface that is emmitting light,...
Notes:

4. How to render them

The delux maps store their vector in world space.  The biggest "problem" when rendering them is converting the world space vector to tangent space (to dot it with the normal map).  Normally we can convert to tangent space at the vertex level and then use a renormalization cube map or similar to renormalize them.  With delux maps this has to be done using per pixel math.  This makes it impossible to use on Geforce2 level hardware and makes it a 2 pass algorithm for Geforce4 level hardware.  On modern hardware (Radeon9500+ and Geforce Fx) this can easily be done in one pass.
Once the delux map is converted into tangent space we render it very similar to ordinary bumpmaps.

5. Problems and ideas

Delux Lightmap Delux & Light "Real" bumps

6. Contact

Charles Hollemeersch  (Questions on the engine side of things)
ydnar(Randy Reddig)  (Questions on the compiler side of things)

Thanks to
Willi Hammes (for the level textures)
James Hastings-Trew (for the "gargoyle" textures)