0
$\begingroup$

I'm writing a shader that creates a grid with coloured tiles. The color is derived from a pixel at that location on a texture. But around the tiles I get these unwanted seams.

I can't seem to figure out how to get rid of those, I tried interpolating with the neighbouring cells.

Suggestions on the web point to setting texture clamping/wrapping to get rid of seams, but that's only a valid solution when I'd sample near the border of the source texture.

Update: I've created a shadertoy sketch to demonstrate the problem: https://www.shadertoy.com/view/7lV3zz

enter image description here

Code

#ifdef GL_ES
precision highp float;
#endif

varying vec2 v_texcoord;

uniform sampler2D u_source; // ./assets/textures/moon.jpg


void main() {
  vec2 st = v_texcoord;

  float scale = 20.0;

  vec2 uv = st * vec2(scale);
  vec2 ipos = floor(uv);      // col & row index on the grid (0, 1, 2, 3, ..., 80)

  vec2 iposSample = (ipos + vec2(0.5, 0.5)) / vec2(scale);
  gl_FragColor = texture2D(u_source, iposSample);
}
$\endgroup$
2
  • $\begingroup$ what is the setup of the sampler? If you look closely every one of the tiles has an extra line of pixels on it . $\endgroup$
    – pmw1234
    Nov 16, 2021 at 22:20
  • $\begingroup$ I've added a shadertoy sketch to demonstrate the problem. I'm pretty sure it's not a texture setup problem (clamping, wrapping, ...), seams appear in those cases where the position is closing in on the borders of the sampled texture. I'm just sampling aribitrary points away from the borders. I can't imagine this is a mipmap problem either. $\endgroup$
    – polyclick
    Nov 16, 2021 at 23:15

2 Answers 2

1
$\begingroup$

Using texelFetch gives the correct result. Here is a shaderToy that shows an animated version.

void main() {

  vec2 st = v_texcoord;
  float scale = 20.0;

  vec2 uv = st * scale;
  vec2 ipos = floor(uv);      // col & row index on the grid (0, 1, 2, 3, ..., 80)

  vec2 iposSample = (ipos + vec2(0.5, 0.5)) / vec2(scale);

  //gl_FragColor = texture(usource, iposSample);
  gl_FragColor = texelFetch( usource, ivec2(iposSample*imageResolution.xy),0);

}

The samplers do seem to be part of the issue as texelFetch cleans up the output. I wasn't suggesting clamping or wrapping but rather nearest vs linear. I'm not sure what shader toy uses for its samplers, but texelFetch can have a significant effect on shader toy as well.

$\endgroup$
1
  • $\begingroup$ For those using WebGL/GLSL, texelFetch is supported in WebGL2 (OpenGL ES 3.00). If you don't have WebGL2 available, setting up the sampler to use Nearest actually does work, to my surprise :). $\endgroup$
    – polyclick
    Nov 18, 2021 at 10:00
0
$\begingroup$

The problem is due to MIPmapping: the derivative is 0 inside tiles then huge accross (same problem when repeating texture with explicit fract() ). → Either use nearest instead of MIPmap, or compute the LOD manually via textureLod()

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.