Glsl shader fract not wrapping seamslessly

Hi!

I’m trying to write my own shader which use fract to wrap the uv but I’m not getting seamless wrapping on the blue background and green foreground. I don’t know if this is something I have to fix in the shader or from three…

The shader looks like this:


precision highp float;
precision highp int;
precision highp sampler2D;
precision highp samplerCube;

uniform float iTime;
uniform sampler2D stoneTexture;
uniform sampler2D treesTexture;
uniform vec2 auv;
varying vec2 vertexUV;
varying vec3 vertexNormal;

void main() {
  vec2 uv = vertexUV;
  float xSpeed = -0.01;
  float stonesScale = 1.8;
  vec2 spaceVertexUV = fract(uv * stonesScale + vec2(sin(iTime * -0.01), iTime * -0.0001));
  float li = texture2D(stoneTexture, spaceVertexUV).r;

  float v = uv.x + li * 1.1;
  v = 1. - abs(v * 1.0 - 1.);
  v = pow(abs(v), 10.0 + sin((iTime * 0.15 + li * 0.1)));

  vec3 startColor = vec3(0.05, 0.05, 0.3);
  vec3 endColor = vec3(0., 0.05, 0.5);

  vec3 col = mix(startColor, endColor, smoothstep(0.0, 1.0, uv.y));

  float x = (1. - uv.x * 0.6) * 0.6;
  float y = (1.0 - abs(uv.y * 1.0 - 1.0)) * 1.5;
  col += stars(uv, 5.);
  col += vec3(x * 0.4, y, x) * v * 1.2;


  //trees
  vec2 treesuv = fract(vertexUV * auv);
  vec4 maskColor = texture2D(treesTexture, treesuv);
  vec4 fgColor = vec4(0.1, 0.5, 0.1, 1);
  float alpha = maskColor.r;
  col = mix(fgColor.rgb, col.rgb, alpha);

  gl_FragColor = vec4(col, .5);
}

And from js I’m loading the textures like so:

const stoneTexture = useLoader(TextureLoader).load('/textures/blurred-stones.png');
const treesTexture = useLoader(TextureLoader).load('/textures/trees-001.jpg');

I made sure the images are both 2048x2048 pixels and there are no artifacts in the images themselves.

Any help appreciated!

Can you try setting the wrap modes on the textures like


stoneTexture.wrapS = stoneTexture.wrapT = THREE.RepeatWrapping
treesTexture.wrapS = treesTexture.wrapT = THREE.RepeatWrapping   ?
1 Like

Thank you for the suggestion!

I tried it but unfortunately it didn’t make a difference :slightly_frowning_face:.

const treesTexture = useLoader(TextureLoader).load('/textures/trees-001.jpg');
await treesTexture.then((texture: THREE.Texture) => {
   texture.wrapS = THREE.RepeatWrapping;
   texture.wrapT = THREE.RepeatWrapping;
   myuniforms.treesTexture.value = texture;
});

Now that texture wrap is set up, you can just delete all the “fract” yeah?

if it still isn’t wrapping correctly at that point, then your textures might not be wrapping textures?

1 Like

It works! Thank you so much!

Once I removed fract the seams are gone. I was 100% sure fract was the way to go. I guess I have some reading up to do. Thanks, I would never have figured that out myself.

1 Like

Ya i’ve gotten bit by the same thing before.
I think fract makes the fragment derivatives unpredictable, resulting in seams.

Glad it worked!

1 Like