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:

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.


This is what the distance fading mask looks like:

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.

This is what it looks like in the shader:

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.


This results in a more organic looking slope edge:

The final result is nice and fairly cheap:

Visit the Godot Tutorials main page for more Godot tutorials.