I’m very happy with a lot of the changes in Alpha 44; a bunch of the seemingly less-consequential AI improvements, such as the stockpile rewrite, seem to have been very well received. I therefore decided to do something fun last week on Thursday and Friday, and start rebuilding the rendering pipeline to support interior and dynamic lighting. On our old development report this was actually the last rendering ticket.

The thing that made me grumpy about the interior rendering is that we don’t want exterior dynamic lights to leak into the interior – if you put an outside light on a building, you don’t want it shining in the interior. Similarly, you don’t want to have a light inside a building reflecting the outside of the building. Finally, it would be nice if we could set the interior and exterior lighting of the world differently.

The solution I’ve arrived at is to upload an “interior map” to the renderer, which classifies each volume of space (thankfully, we live in a flat world!) as “exterior” or “interior”. We can then use different lighting values for each, and dynamic lights marked as being “outside” can then only light exterior squares (and vice versa.) In practice, you get things like this:

We might have a per-building color table, or some way of making buildings run by maddened overseers… ah, “more ominous” (so, probably purple.)

In order to apply dynamic light sources from things like glowing lamps and particle effects, it is necessary to set the renderer up to be a proper deferred renderer again. Right now, it’s not – we actually do all our lighting in a forward pass as of Alpha 44, which is fine when you only have one light. We don’t want to do what is called “light prepass rendering” because I’m really not keen on putting 40 characters through a complex vertex shader twice if I can help it, and we can have a lot of objects and batches on screen (something I am still trying to reduce.) So unlike, say, a first person shooter, classical deferred rendering is still a good choice for us.

Because we have unique needs, we have shoved all kinds of nonsense into our multiple render target G-buffers. We now have:

BUFFER 0: (Normals X, Y, Z; Global Directional Light PCF Shadow Map)

BUFFER 1: (Albedo X, Y, Z; Outline for Sobel Filter)

BUFFER 2: (Glow Buffer X, Y, Z; a blank space, which gets filled by the AO shader so we can downsample our AO and our glow in the same pass)

BUFFER 3: (Specular Power; Specular Intensity; Interior/Exterior; ???)

This gives me one last thing to play with in case of emergencies. I don’t know what will go in that last float, I’ll think of something. As a consequence of all of this, I was also able to delete and clean up a lot of shaders last week, and put the glow back in! I’m not happy with how the glow is currently blurring, but I suppose I will fix that when I get there. Putting the light in the PCF shadow map gives me a little more control over biasing things, so I can(for instance) use a different bias for the terrain versus a character. There are still some scuzzy artifacts on the shadow maps for characters sometimes, especially some of the dress models, but I can clean those up whenever I have some time for cursing and swearing at a thing.

Otherwise, I’m cleaning up memory leaks and a few other pieces of fun this week, then desperately trying to finish the AI editor so I can start on the military AI; it has been decided that, since I am making a new AI tool for decision trees, I get to eat my own dog food for the rest of the month and we’ll see how it goes!