"If an exchange between two parties is voluntary, it will not take place
unless both believe they will benefit from it. Most economic fallacies
derive from the neglect of this simple insight, from the tendency to assume
that there is a fixed pie, that one party can gain only at the expense of
another."
- Milton Friedman

Framework 3 (Last updated: February 6, 2017)
Framework 2 (Last updated: October 8, 2006)
Framework (Last updated: October 8, 2006)
Libraries (Last updated: September 16, 2004)
Really old framework (Last updated: September 16, 2004)
Dynamic lightmapping
Sunday, August 20, 2006 | Permalink

Executable
Source code
DynamicLightmapping.zip (1.1 MB)

Required:
Pixel shader 2.0
Vertex shader 1.1
Generating lightmaps can be a quite time-consuming task, thus they are typically generated offline and shipped with the application. That's also what I've done in the past with the demos that use lightmaps. Even though my lightmap generation code probably could be optimized a fair bit, I doubt any CPU implementation could get anywhere close to the performance you can get by offloading this task to the GPU, which is what this demo does.

First a position map is generated on the CPU. The position map contains the worldspace position that each pixel in the lightmap maps to on the geometry it's used with. The position is preprocessed a bit to push it out slightly from the geometry to avoid precision problems. It's particularly important since I generate four position maps to antialias the shadow slightly, and the offset sample positions cannot cut into the geometry or you'd get artifacts.

The shadows are generated with a standard cubic shadow mapping technique, except it's done in texture space of the lightmap with the position looked up from the position map. The process of generating the shadow map is quite fast and definitely real-time if you're doing plain hard shadows. The texture filter will then smooth the edges a bit to get somewhat soft shadows. This is slower than just doing shadowmapping directly though and the quality improvement is relatively small. It does give you the option to blur the shadow in lightmap space, which is cheaper than doing it per pixel with regular shadow mapping. However, in order to really differenciate from plain shadow mapping this demo implements real soft shadows with the light sampled at 512 positions. The shadow for each light position sample is also 4x antialiased. The antialiasing was added since it adds some extra quality especially with a small light radius and adds very little to the cost (generating the shadow map is the bottleneck). Generating this soft shadow is almost real-time, but not fast enough to do every frame. However, once it's been generated it can be reused forever and give you soft shadows nearly for free.

Typical applications of this technique could be to either generate lightmaps fast on end-user machines to reduce download size, or for semi-dynamic lights in games, where the light position is expected to remain static most of the time, such as lighting up a candle.

This demo should run on Radeon 9500 and up and GeForce FX 5200 and up.

On the first run it will generate four position maps, so it may take up to maybe 10 seconds to load. Later runs will start much quicker.