Cheap Godot terrain shader

Last Updated on 30. May 2025

The purpose of this shader

I needed a somewhat cheap terrain shader for the video game I’m currently developing in the Godot engine (see my post about the tree shader if you are interested). I aim for low hardware requirements and a certain aesthetic, so there are a few things to consider.

Here’s the entire shader. Feel free to use and modify it. Attribution is always welcome but not required.

I prefer the oldschool look of handmade terrains where the ground and walls don’t have visible mesh seams and instead smoothly flow into each other. That’s why instead of relying on height maps and countless rock props, I’m sculpting the terrain as a low poly mesh in Blender. I won’t go as far as manually modeling everything face by face, because my desired polygon density is too high for this approach.

The backdrop mountain range terrain will be even lower res in the final pass, but I’m not overoptimizing anything at this stage. I’ll probably retopologize the backdrop parts manually at some point to go as low as possible while maintaining proper shading.

This will be a vehicle combat game, so the ground detail doesn’t need to be crazy high. I’m using an edge length of a bit more than 2 meters for the ground tringles, which is more than enough to drive around smoothly even on rougher ground.

I don’t want to use triplanar projections, because this operation is too expensive and can cause blurry transitions at certain angles. This saves me some runtime costs, but makes it necessary to create UVs.

During the early development phase of this game, where levels still change regularly, I’m not going to spend much time on creating UV seams. Instead, I’m relying on Blender’s Smart UV Project feature and then apply a fixed texel size for consistent outcomes. I’ll create proper UVs later in development, when levels don’t change that much anymore. That’s why I’ll have to live with visible UV seams like on this cliff side here for the time being:

Visible UV seams on the cliff. Not a limitation of the shader, just lazy UVs

I also want to blend automatically between a ground and a wall texture based on the slope. This saves me a lot of time because I don’t have to manually define which texture goes where, I can focus on creating the shape instead.

I want to keep texture memory low, so the shader only uses 3 diffuse textures and two procedural mask textures.

And lastly, I want to avoid visible tiling in the distance, both on walls and the ground.

Wall texture blending

Let’s look at the walls first. They use Godot’s DistanceFade node to fade between the same diffuse rock texture with two different scalings. The transition is obvious in this isolated case, but unnoticeable during gameplay and with more detailed geometry.

Fading between two differently scaled versions of the same wall texture
The wall texture is blended with itself at another scale
Godot’s DistanceFade shader node used for blending the two textures

This is what the distance fading mask looks like:

The DistanceFade mask

Ground texture blending

The distance fading applies to the ground as well, but there is another layer added in when the camera is close. Take a look at the video first. Try focusing on the soil spots that form when the camera zooms in and how the overall ground changes when zooming out.

The soil parts are exposed by using a simple noise mask that uses a different tiling and rotation than the two ground textures. This breaks up texture tiling up close and makes the ground more interesting. The soil fades away in the distance to avoid too much noise. The mask is a procedural noise created in Godot.

The mask for the soil texture. Ignore the hard seams, as they are caused by the placeholder UV mapping

This is what it looks like in the shader:

The nodes responsible for the ground texturing

I initially thought it would be necessary to break up the ground and wall tiling in the distance as well, but this could be skipped entirely. This is because the player never looks at the ground from up high enough to notice any tiling in the distance. And walls are never large, flat and empty enough to cause any problems. The terrain’s shape and the props can hide any tiling well enough.

Slope masking

The automatic slope masking is mainly carried out by calculating the dot product of the terrain mesh’s normal and the transformed view matrix. This value is then fed into a SmoothStep node. This node is used to control the angle and sharpness of the slope.

This is what the mask looks like in action:

To break up the slope’s uniform edge, the slope mask is then fed into another SmoothStep node that takes a procedural grainy noise mask as its other input.

The noise mask for breaking up the slope mask
Both masks are combined

This results in a more organic looking slope edge:

The slope mask combined with grainy noise

The final result is nice and fairly cheap:

The final outcome

Visit the Godot Tutorials main page for more Godot tutorials.

Scroll to top