Hi there! Welcome back to the Blightmare developer blog. Today's post is a continuation of our ongoing series about 2D lighting. Specifically, we're going to start looking at some performance improvements because with all our recent effects, there are some areas that are so slow they can't really be played and that's no good. This is only a first pass at making some improvements. I'm sure there will be many more passes before things are ready to ship. Anyway, let's take a look.
In order to get an idea of what might be happening, I built a quick test level in our editor that had decorations on all our layers, mechanics, shadows, everything. The level looks like this in the editor:
In order to try to keep this post a little bit more concise, I'm going to omit some of the profiling that I did initially which pointed me at the new graphics features. However, I would recommend against skipping steps in any performance improvement endeavors that you may do yourself. Anywho, I fired up play mode and took a look at the frame debugger. Here's what it told me:
1143 draw calls is quite a few. It's more than I was expecting. What's really odd is how many draw calls there are for each lighting layer. None of them are under 70, and several are well over 100. This is all in a scene with 88 placed items. So what's going on? Well, if we think back to the original post about 2D lighting, we had a whole pile of layers that use used to setup the layered graphics that we wanted. The problem with all these layers is that for each layer, we're going to have to compute shadowing and lighting, even if we don't end up using those effects on a layer. This adds up really fast, especially when we have almost a dozen layers.
So what can we do? We still want all the distinct layers that we have, but we don't need lighting and shadowing on all of them, and we can get the same effect by using sort order carefully. The plan is to reduce the number of layers as much as we can so that we have a render layer for each change in graphics effect. In our case, we're going to collapse things down to 4 layers:
- Static background layer without lighting or shadowing
- Parallax decoration layer with lighting but no shadowing
- Interactives layer with lighting and shadowing
- Foreground parallax layer without lighting or shadowing
Within these layers, there are a bunch of distinct sorting groups that are 1000 units apart to make sure we have plenty of room to layer things as we want. I wrote an editor script that automatically sets the layers and sort orders for our prefabs so that we can change the base values easily and globally if we need to in the future.
After running the script and loading up the same level, we see this new frame profile:
Down to 212! That's a good start, and you can clearly see the differences in the shadowing on the hill. We could further combine the layers if we wanted to keep the shadowing on the background, but my artists tell me that we don't want that, and your artists are always right.
With the changes to the layering, the level that was previously slow is now running at about 200fps on my computer which is pretty solid. For a 2D game like Blightmare, we would expect the graphics performance to be very good, so 200fps is still a bit lower than where we should be, but as I said at the start, this is just the first pass.