Friday Facts #214 - Concrete rendering

Posted by Posila on 2017-10-27

Hello, there has been an illness running around the office this week, so productivity has been down. Regardless, it is still friday, so here are the Factorio Facts.

High-resolution concrete

It seems concrete became the main ground texture of most megabases, which is something we didn’t expect when we added the stone and concrete 'paths' a few updates back. Since we are remastering all sprites into high resolution, we decided to redesign concrete to fix some issues we have with it:

  • It has a visible grid that doesn’t match the tilted projection of the game.
  • It doesn’t seem to have any height.
  • Hazard concrete transition to concrete is very sharp which makes it look too artificial.

When drawing terrain, we try to hide the fact it is composed of repeated square tiles. For this reason we use various tile sizes, where bigger tiles can have some larger features that wouldn’t fit onto a smaller one. This solution was not good enough for concrete rendering any more.

We were inspired by an article about detail textures, and decided to try to draw concrete in two layers - material and detail. The idea was that we would create a larger material texture that would be laid out in a regular grid under the whole world, and we would cut out the shape of the concrete placed over it. Then on top of the material, we would add some detail defined in our regular 1x1, 2x2 and 4x4 tile sprites.

We experimented with this and liked the freedom from having to create 32 by 32 pixel sprites that need to tile with each other. For other terrain types we use prerendered transition sprites on border between two terrains, but because of the material layer, we needed to render transitions at run-time. To finish this up, we needed to add alpha masking to our rendering capabilities. The alpha mask is a greyscale or single channel image which is multiplied with the actual texture, so that a pixel in the texture becomes more transparent the darker the corresponding pixel in the mask is. Now that we have this capability we can replace the prerendered transitions with masks, that are shared by multiple terrains, so we will save some video memory. This will be big deal when we do transition from any tile type to water.

In 0.15 we made a change that merged concrete and hazard concrete transitions to other terrains. Initially hazard concrete had its own graphic for the transitions, but the algorithm that was drawing them produced flawed results in some edge cases, so we decided to use the same transition graphic as normal concrete does.

To fix the flaws of the original drawing algorithm, we render transitions in two passes. First we resolve transitions as if all hazard concrete was regular concrete, then we render transitions just for the hazard concrete. This also allows us to create irregular edges between hazard and normal concrete. In the end we didn’t use normal tile sprites to add any additional detail, but we used normal (non-masked) transition sprites to add a border from the concrete bricks. The following GIF illustrates how individual layers are added together.

In some way it's a pity that we decided to tackle the concrete last, as we could have used this functionality for all the other terrains. The final result is a much better and easier system to work with, and will allow the artists to create the best art without worrying about the technical considerations too much.

These improvements lead to other ideas to improve our graphics rendering, and a lot of difficult issues are still left to be resolved, so let us know what you think on our forum.