Public Group

This topic is 3204 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi all, I am trying to add an automatic texture option to my terrain editor. The terrain is rendered (and saved) using a colourmap (r,g,b,a channels so four textures to work with, I'm thinking grass, dirt, stone/rock, and snow (r,g,b,a respectively) I am just having trouble thinking out the algorithm to achieve this, I have access to the mesh data per vertex (height and normal). I'm thinking :
...
if(height < stoneStartHeight)
use grass
else if(height < grassEndheight)
use blend of grass and stone
else if(height < stoneEndHeight)
use stone
...

How should I go about blending the texture over the overlap for a smooth transition between textures? How should the normal data be incorporated? (e.g. grass will not grow on steep slopes so use dirt, same for snow and stone). Is there anything else I'm overlooking? I am tied to just the four textures due to the use of a colourmap, I know more can be done with a shader, but I really want to keep the colourmap for simplicities sake. (I also know I could have another texture for r+g+b+a = 0, but again for simplicity I don't want to alter any code outside the function for altering the colourmap. I have tried searching but cannot find any relevant sources for this (the ones I can find all seem to go too far in depth, or keep it too simple). Any help/advice would be appreciated. Thanks!

##### Share on other sites
Quote:
 Original post by p0is0nHow should the normal data be incorporated? (e.g. grass will not grow on steep slopes so use dirt, same for snow and stone).

Use the normal's up component (e.g. normal.y or normal.z depending on which way is "up" for you) as one of your rules.
e.g.
if( normal.y > 0.5 )  use rockelse if( height < 100 )  use grasselse  use snow
Quote:
 How should I go about blending the texture over the overlap for a smooth transition between textures?
Instead of writing the rule as "if this condition is true, use this texture", generate a weighting for "how true" each rule is.

In the code below, saturate is a function like:
float saturate( float in ) { return min( 1, max( 0, in ) ); }
e.g. Instead of a grass/snow transition at height==100, make the weights blend from 90 to 110.
grassWeight = saturate( (height-90) / (110-90) )snowWeight = 1 - saturate( (height-90) / (110-90) )
You can do the same for the slope rule to get a nice blend:
rockWeight = saturate( (normal.y-0.5) / 0.01 )
Lets say you want the slope rule to override the height rules. We can multiply the height-based weights by the inverse slope-weight.
invRockWeight = 1-rockWeight;grassWeight *= invRockWeight;snowWeight *= invRockWeight;
Finally, you normalise all your weights:
totalWeight = grassWeight + snowWeight + rockWeight;grassWeight /= totalWeight;snowWeight /= totalWeight;rockWeight /= totalWeight;

##### Share on other sites
I really liked Ysaneya's terrain texturing solution in his dev journal. Linky

##### Share on other sites
Thanks a lot for the help.

I ended up using :
//Declare and initialise the weightsfloat dirtWeight(0.0f), grassWeight(0.0f), snowWeight(0.0f), rockWeight(0.0f);//Set the weightings based on heightsif(height < 190.0f)	dirtWeight = 1.0f;else if(height > 190.0f && height < 250.0f){	dirtWeight = 1 - Saturate((height - 190.0f) / (250.0f - 190.0f));	grassWeight = Saturate((height - 190.0f) / (250.0f - 190.0f));}else if(height < 440.0f)	grassWeight = 1.0f;else if(height > 440.0f && height < 490.0f){	grassWeight = 1 - Saturate((height - 440.0f) / (490.0f - 440.0f));	snowWeight = Saturate((height - 440.0f) / (490.0f - 440.0f));}else if(height > 490.0f)	snowWeight = 1.0f;//Set the weightings based on normalsrockWeight = Saturate((0.6f - normal) / 0.01f);//Override the height rules with the normal rulesfloat invRockWeight = 1 - rockWeight;dirtWeight *= invRockWeight;grassWeight *= invRockWeight;snowWeight *= invRockWeight;//Get the final weightingsfloat totalWeight = dirtWeight +  grassWeight + snowWeight + rockWeight;dirtWeight /= totalWeight;grassWeight /= totalWeight;snowWeight /= totalWeight;rockWeight /= totalWeight;

I have played about with the values and found that these values give the best results, although I might make the grass section end higher up.

Thanks for the help, I was confused about the weightings and first but think I've got a handle on it now.

1. 1
2. 2
frob
15
3. 3
Rutin
12
4. 4
5. 5

• 13
• 12
• 58
• 14
• 15
• ### Forum Statistics

• Total Topics
632124
• Total Posts
3004237

×