# Noticable seams when blending textures

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

## Recommended Posts

For my terrain I have 4 available textures which I am choosing/blending based on the pixels coordinates and the surface normal. For example I can choose to use a rocky texture for steep slopes, grass for low elevation, snow for high elevation, etc.

Right now I am testing the function just blending two textures.When the texture normal.y is less than 0.95 I use the grass texture. When the texture noramal is greater than 0.99 I use the stone texture. When in-between, I linearly interpolate between the two.

Here are the driving functions:

float myInterp(float x1, float y1, float x2, float y2, float x)
{
float m=(y2-y1)/(x2-x1);
float b=y1-m*x1;

return (m*x+b);
}

vec4 ComputeTexture(vec2 TexCoord, sampler2D rock, sampler2D grass, sampler2D stony_grass, sampler2D stone)
{
vec3 _Normal = normalize(Normal);

if (_Normal.y <= 0.950f)
{

return texture(grass, TexCoord);
}

if (_Normal.y <= 0.99f)
{
float weight=myInterp(0.95f,1.0f,0.99,0,_Normal.y);

vec4 color= ( texture(grass, TexCoord)*weight + texture(stone, TexCoord)*(1-weight));
color.a=1.0f;
return color;
}

return texture(stone, TexCoord);

}


Here is the result:

Notice the seams just outside and running parallel to the stone paths. I've observed the seams seem to occur for far away pixels and disappear when viewed up close.

My textures files are seamless textures, and as is shown in the code, the texture coordinates are the same, it is only the choice of texture that is changing (and the blend weights).

I made sure all textures are of the same resolution, file type, and their sizes are powers of 2.

Any idea what could be causing this?

##### Share on other sites
Although it makes no sense to me, the seams appear where you switch to use either one or two textures (but the math is correct).

Did you try to load both textures in any case and blend them by a clamped weight?
Maybe clamp between [0.01, 0.99] to force two textures. Just to see if it makes a difference.

##### Share on other sites

Thanks for the response, JoeJ.

Based on your response, I tried the following (I didn't do any clamping though)

vec4 ComputeTexture(vec2 TexCoord, sampler2D rock, sampler2D grass, sampler2D stony_grass, sampler2D stone)
{
vec3 _Normal = normalize(Normal);

float grass_weight=1.0f;
float stone_weight=0.0f;

if (_Normal.y <= 0.950f)
{

grass_weight=1.0f;
stone_weight=0.0f;
}
else if (_Normal.y <= 0.99f)
{
grass_weight=myInterp(0.95f,1.0f,0.99,0,_Normal.y);
stone_weight=(1.0f-grass_weight);

}
else
{
grass_weight=0.0f;
stone_weight=1.0f;
}

vec4 color=grass_weight*texture(grass,TexCoord)+stone_weight*texture(stone,TexCoord);
color.a=1.0f;

return color;

}


That fixes the seams! I really don't know why though... haha

##### Share on other sites
No clue either, but i guess there is something different with the textures then. (mip maps or anisotropic filter, ...?)
May be worth to figure out, reading textures for nothing may have some cost.

But in case reading both is ok, you can still remove a lot of branches:

ec4 ComputeTexture(vec2 TexCoord, sampler2D rock, sampler2D grass, sampler2D stony_grass, sampler2D stone)
{
vec3 _Normal = normalize(Normal);

float weight=myInterp(0.95f,1.0f,0.99,0,_Normal.y);
weight = clamp(weight, 0.0, 1.0);

vec4 color = weight*texture(grass,TexCoord) + (1.0-weight)*texture(stone,TexCoord);
//color.a=1.0f;

return color;

}


##### Share on other sites

Awesome. Thanks so much for your help, JoeJ!

1. 1
2. 2
Rutin
16
3. 3
4. 4
5. 5

• 26
• 9
• 11
• 9
• 9
• ### Forum Statistics

• Total Topics
633716
• Total Posts
3013499
×