Is there a way to splat more than 3 textures onto the terrain?

I have created a terrain. And it currently uses a dirt, grass and stone texture, however i really need to add a sand and a snow texture as well. Is there any way to do this? Do i need to modify the existing Terrain.jm3d? And if so, how do i edit and re-implement it?

Thanks in advance :slight_smile: :slight_smile: :slight_smile:

I have read through this:

https://wiki.jmonkeyengine.org/legacy/doku.php/jme3:advanced:jme3_shaders

But im not sure how to implement it into my problem :confused:

Have you opened up the TerrainLighting.vert/.frag and had a look at them?

The # of Textures is hardcoded into the MatDef and shader files.

  • Make a local copy of the j3md, .frag & .vert files
  • Edit the j3md to point at the local copy of the shader files
  • Add uniforms for more Textures
    ** Texture someSplat (in the MatDef)
    ** uniform Sampler2D someSplat (likely only in the frag file)
    ** update the existing frag code to utilize the new texture as well (everything you need is there already… cut, paste & rename uniform references)
  • Point your spatials material at the new local j3md

And you should be good to go.

1 Like

Thank you so much for your time :slight_smile:

@TastyLemons said: Thank you so much for your time :)

If you run into any issues, just post here and either I or some other super awesome nice money-worthy person should be able to help.

Out of curiosity, is the texture set to 3? if so, it’s more than likely due to the trilinear texture mapping option. If you’re not using it, ignore it, or remove the relevant code.

EDIT: Heh… guess if I had read the TITLE a bit closer, I would have seen the number 3 >.<

1 Like

In the .frag file, where it defines which color is used with which alpha channel:

vec4 outColor = tex1 * alpha.r; // Red channel
outColor = mix( outColor, tex2, alpha.g ); // Green channel
outColor = mix( outColor, tex3, alpha.b ); // Blue channel
outColor = mix( outColor, tex4, alpha.??); // ?? channel

Is it possible to add a new Color? Say RGB (20, 20, 20)?

@t0neg0d said: If you run into any issues, just post here and either I or some other super awesome nice money-worthy person should be able to help.

Out of curiosity, is the texture set to 3? if so, it’s more than likely due to the trilinear texture mapping option. If you’re not using it, ignore it, or remove the relevant code.

EDIT: Heh… guess if I had read the TITLE a bit closer, I would have seen the number 3 >.<

Sorry to bug you so much. Its just, if my code doesn’t work, i simply cannot sleep :stuck_out_tongue: Sometimes i stay up all night just staring at one problem :stuck_out_tongue:

@TastyLemons said: In the .frag file, where it defines which color is used with which alpha channel:

vec4 outColor = tex1 * alpha.r; // Red channel
outColor = mix( outColor, tex2, alpha.g ); // Green channel
outColor = mix( outColor, tex3, alpha.b ); // Blue channel
outColor = mix( outColor, tex4, alpha.??); // ?? channel

Is it possible to add a new Color? Say RGB (20, 20, 20)?

Sorry… needed to look at the .frag file. Eeek. That’s a freakin’ mess of directives >.<

What it looks like the frag is doing is using a single texture to store 3 different blend maps, 1 in each channel:

alpha.r = some value between 0.0 & 1.0 (transparent to opaque)
alpha.g is storing another set of values to blend in a different image.
alpha.b as well

So, the shader alots more diffuse texture use based on the number of alpha maps you supply:

If you supply 1, it blends 3 diffuse maps (textures with terrain-y stuff in them)
If you supply another alpha map, you can add 3 more diffuse maps…
Up to a total of… um… math hurts… 12 textures.

The important part is creating the alpha maps properly.

I hope that is more helpful, I hadn’t looked at the TerrainLighting stuff in forever… and it looks like it has been changed significantly since then.

In case it is what you need (info that is)… if you have photoshop:

Render clouds into a layer, turn off all channels except red,
Render clouds into a layer, turn off all channels except green,
Render clouds into a layer, turn off all channels except blue,

This gives you the basic idea of how to create a proper alpha map…

TILT!! :stuck_out_tongue: So it is not possible to simply say something like:

texture1 corresponds with rgb(50,50,50)
texture4 corresponds with rgb (0,0,0)

Im new to shaders, so im not really sure how to supply more alpha maps? Im sorry :confused: I fell bad for asking so many questions.

@TastyLemons said: TILT!! :P So it is not possible to simply say something like:
texture1 corresponds with rgb(50,50,50)
texture4 corresponds with rgb (0,0,0)

Im new to shaders, so im not really sure how to supply more alpha maps? Im sorry :confused: I fell bad for asking so many questions.

In a word: no.

It would look horrible, too, because you’d have to turn off all filtering and you’d have hard edges between every transition.

@t0neg0d said: In case it is what you need (info that is)... if you have photoshop:

Render clouds into a layer, turn off all channels except red,
Render clouds into a layer, turn off all channels except green,
Render clouds into a layer, turn off all channels except blue,

This gives you the basic idea of how to create a proper alpha map…

I generated my Alpha Map based on my generated heightmap. So each texture appears at a certain height:

Rock on mountains
grass in the middle
Mud at the very bottom

So i wanted to add snow to the peaks, using an extra color. So what you are suggesting, i generate 2 alpha maps, and do this:

vec4 alpha1 = texture2D( m_Alpha1, texCoord.xy );
vec4 alpha 2 = texture2D( m_Alpha2, texCoord.xy );

vec4 outColor1 = tex1 * alpha.r; // Red channel
outColor1 = mix( outColor1, tex2, alpha.g ); // Green channel
outColor1 = mix( outColor1, tex3, alpha.b ); // Blue channel
gl_FragColor = outColor1;

vec4 outColor2 = tex4 * alpha.r; // Red channel
outColor = mix( outColor, tex5, alpha.g ); // Green channel
outColor = mix( outColor, tex6, alpha.b ); // Blue channel
gl_FragColor = outColor;

AlphaMap Generator:

http://hub.jmonkeyengine.org/forum/topic/heightmap-based-alpha-map/

Yep yep, though, I’m not sure if TerrainLighting is used for height based texturing… one sec.

It looks like there is a HeightBasedTerrain.j3md + shader files that is used for this.

https://code.google.com/p/jmonkeyengine/source/browse/trunk/engine/src/terrain/Common/MatDefs/Terrain/HeightBasedTerrain.j3md?r=7542

Do you know which shader is being used in your case?

Using height alone for biomes isnt the way to go about doing it because it won’t be very nice to look at and you can predict where biomes will be very easily - and also avoid certain biomes as a result. People use voxel-based engines to do things like this for good reason - you can specify a texture for each block instead of a huge chunk of terrain.

If you want a decent biome spread use many noise generators (maybe one for humidity and one for temperature) and use those values to create a whittaker diagram.

That’s how it’s done (in a nutshell) - and hence the explosion of voxel-based engines. If you’re feeling extra inquisitive you could also read up on this article. The whole book is like a bible tbh. Definitely worth a read, even if you dont understand most of it.

1 Like