I always liked the idea of having a more dynamic lighting model. My thought was that monsters and rooms should have their own light sources (not just the player). I realised that I could use my field of view (FOV) implementation to determine light values for tiles around a light source.
Using the FOV code from the previous articles I was able to simulate which tiles were lit around a specific light source. This was cool, but I also wanted to simulate light attenuation. This means that the light intensity decreases as it moves away from the light source. There are various ways to calculate this, one is the inverse square law. For my implementation I made use of a general inverse quadratic function listed below.
f(d) = 1 / (a0 + (a1 * d) + (a2 * d2))
My current implementation uses a0 = 1, a1 = 0.3 and a2 = 0. The following screen shot shows the light source around the player using the above formula to adjust the light intensity values.
The next step was to add additional lights to the dungeon. This called for a rethink of my drawing routines. I came up with a layered approach.
Draw the architecture (the dungeon)
Draw the actors (right now only the player)
Apply lighting to the scene.
I already had the first two steps working quite nicely, but I needed some way to take care of the lighting.
To solve this I created a new LightMap class that would handle the required processing.The LightMap class processes all the static lights in the scene and caches the results. For every render pass I recalculate all the dynamic lights (player light source) and store their values in the LightMap. For overlapping lights I made use of a simple additive algorithm to add the light values.
After rendering the scene I perform an additive alphablend of the LightMap values to produce a result as shown below.
The screen shot above shows a square room with four static lights, one in each corner. I specified a different colour for each light just to show that its possible.
My FOV is currently set to a radius of 10 around the player. The player can, however, only see tiles that are lit by light sources. That’s why there’s a black area in between the player light and the four lights in the corners. I have no idea how this plays in a real game, but for now I’m happy with the aesthetics.