5.5. Generating light maps

This is a feature closely related to ray-tracer routines, although it doesn't actually involve any recursive ray-tracing. The idea comes from the realization that we already have a means to calculate light contribution on a given point in a scene, including checking what lights are blocked on this point. So we can use these methods to calculate lighting on some surface independent of the camera (player) position. All it takes is just to remove from lighting equations all components related to camera, which means just removing the specular component of lighting equation. We can do it even for any point on a scene (not necessarily a point that is actually part of any scene geometry), as long as we will provide material properties that should be assumed by calculation.

What do we get by this? We get the ability to generate textures that contain accumulated effect of all lights shining on given surface. This includes shadows. We can use such texture on a surface to get already precomputed lighting with shadows. Of course, the trick will only work as long as lights are static in the scene and it's not a problem to remove specular component for given surface. And remember to make the texture large enough — otherwise user will see that the shadows on the wall are pixelated and the whole nice effect will be gone.

I used this trick to generate ground texture for my toy lets_take_a_walk. Initially I had this model:

Figure 5.1. lets_take_a_walk scene, side view

lets_take_a_walk scene, side view


Figure 5.2. lets_take_a_walk scene, top view

lets_take_a_walk scene, top view


Using our trick I generated this texture for the ground. Note how the texture includes shadows of all scene objects. And note how the upper-right part of the texture has a nice brighter area. Our OpenGL rendering above didn't show this brighter place, because the ground geometry is poorly triangulated. So OpenGL rendering hit again the problems with Gouraud shading discussed in detail earlier in Section 3.7.2, “Triangulating”. It's a quite large texture (1024 x 1024 pixels), but any decent OpenGL implementation should be able to handle it without any problems. In case of problems, I would just split it to a couple of smaller pieces.

Figure 5.3. Generated ground texture

Generated ground texture


Finally, resulting model with a ground texture:

Figure 5.4. lets_take_a_walk scene, with ground texture. Side view

lets_take_a_walk scene, with ground texture. Side view


Figure 5.5. lets_take_a_walk scene, with ground texture. Top view.

lets_take_a_walk scene, with ground texture. Top view.


Such textures may be generated by the gen_light_map program included in the castle_game_engine/examples/vrml/tools/gen_light_map.lpr file in our engine source code. The underlying unit responsible for all actual work is called VRMLLightMap. lets_take_a_walk source code is available too, so you can see there an example how the gen_light_map program may be called.