Developer postOriginal post (opens in a new tab)

Static Lighting

The size of levels in Space Trucker requires there to be several hundred or even thousands of lights depending on the scope being obtained. In order to maintain performance it is necessary to find a reliable method of pre-mapping the lighting data that would normally be rendered in real-time while the game was running.

There are other rendering methods such as deferred rendering but these are not silver bullets since you lose out on things like multiple transparencies (looking through a window, that looks over the street, into another window into another building) would be impossible using deferred rendering so this is not a valid way to solve our problem since many of the levels have setups like this where windows and doorways may look into other areas, that will contain windows that look into other areas and so on and so forth.

For the development of Space Trucker we will look to older ways for guidance in this matter. Before the age of using dynamic lights and shadows for absolutely every dynamic entity on the level there was a method known as pre-baking or static lighting which would create a 2D overlay of your lighting data known as a lightmap. This data would then be used at runtime, combined with the UV unwrapping capabilities on the model, and the multi-layered material system we can lay the baked lighting image on top of the diffuse texture used by the level to make one big happy material shader for our level that can be used at run-time.

Above is an example of the map editor compiling the lighting data for a given level, the black space on the right is the actual lights being baked into the 2D image for later unwrapping. The reason it looks like a circuit board is because the levels textures are also stored this way. Every wall, floor, and ceiling is texture mapped from a single image which makes loaded very fast and allows for static lighting calculations like this to be possible without having to store the data for each part of the level in different files.

The insanity you see below is what the static lighting manager created for our level, this image is laid literally right on top of the diffuse texture for the level and then UV unwrapping allows the lighting to appear as we intended with the color parameters and roll-off amounts specified by the level designer.

It is worth noting that compiling even a simple image like this can take upwards of 30 or 40 seconds depending on the complexity of the level, how many times light bounces off materials, shadows that are created by light passing through various other entities and how that will be plotted out in the 2D image takes an immense amount of computational power. All the power that would be wasted during runtime of our game, is being done ahead of time now and stored for fast access since it can all be loaded into the computer's memory and not polled from the disk unless it is actually loading such as a level transition which is fine and normal at that point.

Below the drop here are some examples of levels with static lighting being faded from enabled to disabled. It is pretty obvious how much detail and life this can bring to a space, with the static lighting it is possible to have as much lighting as we want on a level with no limits on how many lights there can be.

The entire image that is used by the static lighting manager is only about 16MB worth of memory when compressed using a DDS file and the DX1 format it provides. DDS stands for direct draw surface, and is how the GPU is able to see images as byte arrays in it's own video memory making it easy for things like shaders to manipulate it in real-time before being rendered to the screen.

Next post I am going to talk about the little black book which stores notes, scribbles, ideas, and generally is the reason most developers are able to remember anything at all!