Tue, 06 Mar 2018

Colorful Optimizations

pre-alpha 1810 devlog


Airplanes & Custom Colors

This release contains three different (one refurbished and two new ones) airplane models and the trails of planes using jet engines are shorter to not cloud up the whole map. If you think that the trails are too short now, please let me know. Aside from bringing a bit of variety to the looks of the airplanes, the most noticeable difference is that planes no longer fly in straight lines only! Pilots learned to fly curves and even change course along the way.

Along with the new airplane models I have also reworked how custom colors (through code) can be applied to models. Previously I could only mark whole objects to ‘use custom color’. But now it is just another layer of vertex attributes, allowing to color just segments of a mesh with a custom color. This way I no longer have to create separate meshes just to color tiny parts of a model, instead I can merge everything into one big mesh, saving draw calls during run-time. The orange on the airplanes is where the custom color is applied, which is much more fine-grained than previously possible.

TL;DR: more detailed coloring on models possible, while improving run-time performance.

Markers for Natural Resources

Natural Resources are difficult to represent on the map. A lot of them are subterranean so they are plainly hidden from view. Like many other games I could just display some abstract model on the surface to make them apparent. However this leads directly into the second problem: how are resources noticeable when a building is built on top of them (or a new resource is discovered underneath an already constructed building)? When things like crude oil are represented by a flat oil-seepage all bets are off.

So I dropped the idea of trying to represent them in-world, directly on the map, early on. Instead I opted for an animated model hovering high over the respective tile. This is not unheard of and solved the problems mentioned earlier. However it left me with two new problems: (1) It was hard to recognize the exact tile the animation was hovering above and (2) when zoomed out those animations were just too small, thus it was impossible to see all the natural resource deposits on the map at a glance.

With this release there are dedicated resource markers available. There are 12 different markers (3 shapes x 4 colors) available. The shape and color can be freely selected and enabled for each resource. This can be set up from within the ‘Dataviews’ menu. So if you are only interested in a single natural resource, select a marker for it in the menu and all its deposits are highlighted on the map. Since the markers keep their size no matter the zoom level it is a quick way to get an overview over the available resources when zoomed out to the max.

Status Icons 1

Similar to the problem with resource markers I have changed the way business units display any special status information (i.e. ‘under construction’, ‘storage full’, ‘no input’, …). Now they are also represented via UI icons instead of in-world animations which where hard to see and did not really fit the in-world graphics anyway.

But this is only the first iteration for status icons, since they cannot display multiple states at once. I do have the direction I want to go with them on paper, but I could not squeeze them into this release. Maybe the final status icons will be done for the next release.

Clouds & Wind

First and foremost I changed how clouds are spawned across the map. Previously they just randomly spawned anywhere on the map. And while there are still a few clouds that will do so, the majority of clouds spawn over lakes, as seen in the screenshot.

By clumping clouds together this way they also look much more impressive in-game than a lone cloud ever could. I also added a few more shapes for clouds to make them a bit more diverse and changed the speed of them growing (faster) and dispersing (much slower). In fact, running the game at normal speed makes the clouds look very much static. But on ludicrous speed this is definitely not the case.

The biggest influence on clouds are the map-wide winds. Their directions did not just look static, but they were static. Not anymore: over time the wind directions on the map will change. Again: barely noticeable when running the game at anything other than ludicrous speed.

Optimization of the Vulkan Renderer

While optimizations are the very last of my priorities, the fact that parts of the bloom effect (brightpass + blur) took nearly 7 ms to complete on a GTX 960 was really bothersome. Keep in mind that for running at 60 FPS a single frame only has 16.6 ms to complete. So 7 ms is already nearly half of that; but even more: 0.5 ms I would consider okay, but 7 ms? That is way off, and I seemingly have screwed up big time.

The short version is that I implemented those to parts of the effect as compute shaders and I must have done something very wrong. After rewriting them to use the graphics pipeline they were already down to 0.3 ms to 0.6 ms, which is much more in-line with what I expected for a bloom effect.

Thus no need to optimize any further at this time. Most other sections of the renderer take up more time. And, oh well, looking at the chart the generating and rendering of the shadow volumes really sticks out now. Guess what I am going to conquer next…

Optimization of the Metal Renderer

Since Metal does not support instrumentation under macOS I cannot pin-point where optimization is needed the most. So for the time being I will not touch the Metal back-end for any optimization. There are more important things to concentrate on than taking shots in the dark, hoping to optimize the right parts.

MoltenVK: Last week Khronos (caretaker of the Vulkan API among other things) announced the open-sourcing of MoltenVK, a previously closed-source Vulkan emulation/translation for macOS. Of course this raises two questions for me:

  1. Can it run Margin Magnate (on paper it should be able to, since it supports the required feature set; without the instrumentation of course) and

  2. what is the performance loss compared to a native Metal implementation and how much of the ‘regular’ optimizations for Vulkan translate to performance gains when using MoltenVK.

For me it comes down to this: if MoltenVK swallows 5% of performance while an optimization I apply for Vulkan under Windows, say a performance increase of 10%, directly translates to MoltenVK, I still come out ahead by 5%. Just as a byproduct of improving the Windows version. As a solo developer that is a big thing, since I can either dedicate the same time to optimization but benefiting on both operating systems, or I need to spend less time overall in optimization with the same results, leaving me with more time to spend on other, more pressing matters. And do not forget the lack of instrumentation on macOS, which makes optimizing the Metal renderer rather hard to start with.

Optimizing CPU Usage of the Renderer

For the moment none of the benchmark data indicates an imminent need to optimize the CPU side of things.

However, it is good to see that the design of my engine works out as expected as there are only two sections where 90% of the CPU-time is spent. One is in the Lua animation code and is a matter of optimizing the Lua code. The other is on the C side of things: two nested loops with lots of random memory accesses (read: cache misses). And while the current naive implementation is plenty fast enough, there is enough room to rearrange data to make it more cache friendly (improving performance) if need be.


Enable Javascript to see comments