Noticable seams when blending textures

Started by
3 comments, last by gearifysoftware 7 years, 1 month ago

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:

texture_seams_zpsu2bg5dpi.png

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?

Advertisement
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.

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

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;


}

Awesome. Thanks so much for your help, JoeJ!

This topic is closed to new replies.

Advertisement