"CS has destroyed my life. I can't shower anymore because I think my neighbors use wallhack."

Framework 3 (Last updated: October 11, 2016)
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)
Modern LightMapping
Tuesday, October 11, 2016 | Permalink

Executable
Source code
ModernLightMapping.zip (805 KB)

Required:
Direct3D 11
This demo is an alternative take on LightMapping, inspired a bit by Clustered Shading. I don't know if it's a particularly novel idea, or even particularly "modern", but decided to stick with this name over the alternative "Clustered LightMapping" that I also considered. In any case, after skimming the internet for state of the art implementations of lightmapping it would seem that neither Unreal Engine, Unity or any other popular engine out there, are doing anything similar, even though they have certainly advanced the baked lighting technology since the 90s.

Why lightmapping in 2016? For the same reasons as in 1996 I guess. It can be really cheap and look really great compared to what you can accomplish in realtime with dynamic methods at a far greater cost. About once every year I launch the original Unreal, a game using old-school lightmapping, and find that the lighting has aged really well, whereas for instance its geometric detail is painfully bad in comparison. Often I find that we have sacrificed too much quality in the name of dynamic worlds and iterating time over the last decade or so.

Old-school lightmapping simply stored a light value per texel, which was then multiplied with the diffuse texture and you were done. Unfortunately, that's not really compatible with normal mapping. Some engines solve that by using a lightmap in the distance and dynamic lighting closer up. This demo does lightmapping that's fully compatible with normal mapping, in fact, lighting is computed as with any dynamic light; however, a shadow term is stored for each light, and most importantly, a cluster map stores a bitmask of which lights affect a certain area. The cluster map is sampled with the same UV set as the lightmap; however, it can be of lower resolution. In this demo I made it half-res, but can also be smaller. The result is a lightmapping solution where the lights are stationary, but most attributes are dynamic and can vary, such as color, intensity, etc. If they have a radius, it can also shrink (but not grow), at the cost of some lost efficiency. This demo doesn't use range-based lights though. It would also be entirely possible to rotate the light if it's non-uniform or animate a projected texture. Again, not something I did in this demo. However, the dynamic property of intensity and color is demonstrated and you can interact with the lights in a number of ways.

With this technique it's also trivial to turn lights on and off with a simple bitmask and get all the performance back from the disabled lights. The use of the cluster map improves performance by about 60% compared to evaluating all lights, which presumably roughly matches how many lights affect the average surface in the scene. The scene, as usual, is my own really old and totally awesome coder art.