Unity is an amazing solution for game creation, used by countless indie game developers to produce successful games. But, every now and then, you find yourself battling against some shortcomings.
The absence of a built-in decal system is one such shortcoming, and another is the limited built-in terrain system and tools. This article will show you some techniques for successfully beating the Unity terrain system into submission.
Start with a good data set
(Note on terminology: in this article, when I say “material”, I mean a set of maps – albedo, height, normal, etc. – that makes up a single terrain “texture”.)
It wasn’t long before I headed over to GameTextures and subscribed to their service. This gave me access to a huge library of materials to draw from, enabling me to experiment with many different texture combinations over several months, before finally arriving at the volcanic/desert landscapes that can be seen in the recent versions of our game.
There are various formats to choose from when downloading materials from GameTextures, including “PBR Specular”, “PBR Metallic” and “Substance”. What you go for is highly dependent on your workflow within Unity and the tools and shaders you use.
For example, if you’re simply using the built-in Unity terrain shader, you won’t need height maps. You will need the Albedo maps and Normal maps, and you will need to place the Smoothness values from the appropriate GameTextures map into the alpha channel of the Albedo map, probably using Photoshop.
On the other hand, if you are using something like RTP, you will need to ensure that the texture data you feed this tool is in the correct format according to the tool’s documentation. For example, because RTP uses height-based blending, it will use the height maps from your GameTextures materials.
For various technical reasons specific to our game, we opted for a custom set of shaders coupled with some Unity editor extensions, instead of an existing solution from Unity’s Asset Store.
Whatever workflow and tools you use, you may find this conversion tool helpful in getting your terrain textures into the right format.
Don’t use the built-in shader
Unless you are building a game for mobile phones or tablets, you will probably want something a bit more advanced than the built-in Unity terrain shader.
Our custom shader and editor extensions helped us to overcome two of the biggest limitations of Unity’s built-in terrain system: overly simplistic linear blending between terrain textures, and terrible stretching of vertical terrain textures.
If you’re looking for an existing solution from the Unity Asset Store, a quick search for something like “triplanar terrain” yields good results, including RTP and other less advanced solutions.
What you are after, at a minimum, is something that will do triplanar projection to get rid of vertical stretching, as well as height-based blending for crisp and detailed transitioning between textures. From there, you can go a lot more advanced, depending on your needs.
Many basic terrain systems simply project the textures in a top-down fashion onto the terrain using UV co-ordinates. This results in terrible vertical texture stretching.
This can be remedied by projecting onto three planes instead of one:
To fix the blending, we feed height data to our shader, which is used to blend between various textures, using not only the regular splat control map, but also the per-pixel height values (per-texel filtered).
Increase the cohesion
Unless you are lucky enough to have a dedicated terrain texture artist, you will probably end up with a set of good (or even great) quality textures, none of which were truly designed to work together as a single unit.
For example, in a rocky environment, it helps if the sediment surrounding the rock looks like it actually came from the rock. So, you might find a great texture you want to use as sediment, only to find that it has the wrong hue and looks terrible against the rock.
Each terrain in Infinite Desolation consists of 8 different materials being blended by our custom shader. For simplicity, I will just demonstrate how I modified a subset of these textures – the rock and two sediment variations – to create better cohesion.
You have to start somewhere and treat one of the textures as the “master”, a kind of baseline that the other textures will be modified to conform to.
After much trial and error, I settled on the “Hawaiian Lava Rock” material that you can see in the earlier screenshot taken from the GameTextures website.
The next step was to experiment with many different “sediment” materials to see how the albedo maps, normal maps and height maps come across in relation to the baseline rock.
Part of this process was to adjust the hue, saturation, lightness and contrast of the albedo textures to better match the base rock. In this case, it included actually blending around 20% of the base rock into the sediment textures.
The final chosen rock and sediment textures were modified as follows, with the result shown on the right:
Use better terrain editing tools
There are different approaches for terrain creation, ranging from procedurally generated geometry and texturing, to “painting” all of this by hand. We use both approaches, starting with procedurally generated geometry and texturing (World Creator Professional), followed by manual changes to craft “areas” friendly to the top-down view and enemy horde mechanics of our game.
Whatever the nature of your game, it’s very likely that you will benefit from using a range of terrain editing tools available from the Unity Asset Store.
Here is what we use, and why:
(Note: these tools can do a lot more than the points I’m listing here. I’m simply listing specifically what we get out of them.)
- Allows you to simultaneously paint two different textures targeting different slope ranges. For example, painting a rock face on steep terrain with sediment on less sleep terrain, with adjustable blending.
- Allows you to blur or sharpen the Unity terrain splat map. This is very useful for getting better results out of our height-based blending shader.
- Allows you to paint onto the terrain using a noise filter. This can quickly get rid of visible tiling by randomly blending two different textures.
- Provides vastly improved versions of Unity’s terrain editing tools, such as raising the terrain, lowering the terrain, smoothing the terrain, and so on.
- Allows the addition of custom brushes. We take advantage of this to quickly paint craters, interesting cliffs, etc., into the terrain by hand.
- Carve convincing looking erosion into existing terrain. If your terrain looks a little unnatural and hand crafted, this will quickly remedy the situation.
World Creator Professional
- Procedurally generates your terrain geometry and applies natural looking texturing. This is great for giving us a head start on a terrain, even if we plan to manually edit everything later using the other tools mentioned.
- Comes with a free set of GameTextures materials.
Our game is still in active development, but I’m quite happy with these results. The screenshots shown here are taken from v0.5.0 of Infinite Desolation, which is yet to be publicly released.
You can grab the latest public build of the game from the Infinite Desolation GameJolt page.