Approach for rendering textures over a random ground generator

Hi friends,

I’m doing a basic random ground generator for babylon.js.

It basically creates a base ground (according to some parameters), and then add somef filters like mountains, uneven terrain, etc.

The result can be something like this:

The next step is to render textures over it.

Goal:

My idea is to let the user to choose which textures want to render for different heights and slopes.

Example:

  • For steep slopes, the texture would be rock.
  • For gentle slopes and high heights the texture would be snow.
  • For gentle slopes and low heights the texture would be grass.
  • For heights below water level, the texture would be dust.

Textures and parameters are provided by the user.

Issue:

To build it, my idea is to render all the textures (snow, rock, grass and dust) covering the whole generated ground, then calculate the height and slope of each vertex and apply alpha (0 to 1) to each shader material depending if the material texture has to be rendered or not in that vertex. I hope I described well the issue.

My question:

Before doing it I wanted to ask the experts in the forum, just to know if this approach is correct, or maybe I should follow another approach.

Cheers and have a great weekend!

2 Likes

This sounds like the way to go. Finding the right mix between slope and height might need some iterations. so, try to have some UI for fast iterations/tweaking and debugging.

1 Like

This is the way to go, also have a look at tri-planar mapping to avoid texture distortion on slopes

1 Like

Yep, the plan is doing a UI tool + library that people can use for Babylon.js, apart of including it in my framework.

Thanks, I will look into tri-planar mapping :slight_smile:

1 Like

You may play with https://terrar.babylonpress.org/

It uses custom ShaderMaterial.
I didnt demo it yet since it needs some poliishing.
It is built as a package so could be used in other apps.

1 Like

Wow, thats pretty cool.. and complex.

The one I’m doing is really basic, just to build quick maps for tiny arcade games.

I will take a look to your code to grab ideas from there :slight_smile:

Thanks for sharing!

1 Like

Just do a custom shader with like a splat map then, load up some basic texture for dirt, grass, rock, etc and then paint your splat map with the colors associated with each material type. A custom splat map terrain texture is probably the simplest. You can then also procedurally paint the splat map but thats a whole different conversation.

1 Like

Aww, man, I know there is a technique for it and I remember having seen the code. Cannot find it anymore :frowning:

But it is really simple. You have a range for height layers and a terrain texture per each layer. The code is then as simple as

if vertex.y within(0, 2)
  sample(dirtTex)
//etc.
// some blending on elevation edges 

I do not remember that slopes were handled. Do you need the extra info about slopes at all? Just looking at your screenshot from above, is there any place where “slope” would conflict with “elevation”?

If you look at Labris’s job, I think he’s already dealing with slopes and elevations. I haven’t had time to review the code, but the approach might be very similar to that.

Slopes wouldn’t conflict with elevations since it is the user who decides which textures are rendered for each elevation and slope range.

Slopes are derived from local height differences and then reused by several systems:

  • rivers prefer cells that have enough downhill gradient, so slope helps decide where channels appear

  • steep terrain becomes more rocky, while flatter terrain favors grass or dirt in the material blending

  • flatter areas are preferred for villages, crossings, and road routing

  • moderate rocky slopes and mountain flanks are better candidates for mines

  • very steep areas are poor for foliage placement

So in practice, slope helps decide both how the terrain looks and what can be built or placed on it.

More info here

1 Like