Texture Array Seam

I was experimenting with texture-arrays and i got a weird seam between the texture-array pages i was rendering.
Basically i’m rendering a square polygon with texture coordinates ranging from 0,0 to 4,4.
The idea was to use the integral part of the coordinates to calculate the index of the texture-array and the fractional part for the texture-array page.

If i use this in my glsl:

gl_FragColor = texture2DArray(tex, vec3(fract(TexCoord), 0));

I get a seam:

Yet if i remove the fract:

gl_FragColor = texture2DArray(tex, vec3(TexCoord, 0));

And use GL_REPEAT wrapping, the seam dissappears:

This is the first time i used texture-arrays…
Am i missing something?
Why would that seam appear?
Wouldn’t GL_REPEAT basically be doing the same thing under the hood?

Fract is just the first step in what i’m planning to do (messing around with virtual texture stuff), so i can’t use the GL_REPEAT thing.

Edit: Nvidia hardware btw. (just in case it’s a driver bug.)

Hardware handles the cases for 0 and 1 texcoords specially (afaik).

So, at the coordinate 1 (u or v, doesn’t matter) it is something different, then if it were coordinate 0.

However, with your “fract” you turn EVERY whole number into a 0 coordinate.

So for one fragment the coordinate is 0.999 and for the one next to it, it is 0.0, where it usually is 1.0. I assume this messes up the texture-lookup (plus derivatives etc.).

Might be difficult / expensive to fix this.


Jan is right, that is because of derivative constructions and mip-mapping. I can’t say nothing on special handling for 1 and zero, but when you call “fract”, you always have two neighbor fragments with say (0.999) and (1) coordinates. So gradient construction breakes for that texels.
What you can do - is explicitly suplying gradients for texel fetch. With your approach it is quite simple - just call ddx() and ddy() for texCoord before fraction.

But if that’s the case, why does it still work properly with GL_REPEAT then?
I didn’t show that in the screenshots or the shader code, but if i use -different- texture-array indices it still works with GL_REPEAT…
I also tried adding a value to the coordinates after using fract, but that didn’t move the seam oddly enough

It works with GL_REPEAT not because of GL_REPEAT, but because you removed fractioning from your shader code, and derivatives are constant across whole triangle.

Ah, OK!
So this is how i understand it:

With GL_REPEAT and no fract, one sample coordinate is maybe 2.9 and the one next to it 3.0… a difference of 0.1 … the derivatives are constant, and AFTER that GL_REPEAT does the ‘fract’ internally…

But if i use fract, the sample coordinate is fract(2.9) == 0.9 and the one next to it fract(3.0) == 0.0… a difference of 0.9 … the derivatives are no longer constant, and THAT causes the seam…

The code you should use is something like this:

textureGrad2DArray(tex, vec3(fract(TexCoord.xy), TexCoord.z), dFdx(TexCoord.xy), dFdy(TexCoord.xy))

Yep, that nails it.

Awesome! I got it to work now, thanks!
Just for the record, in case someone finds this post when having a similar problem, it was just “textureGrad” not “textureGrad2DArray”.

Nice tip!

Just using REPEAT is more efficient, though.

Yet, it can be useful to have different wrapping modes per layer :slight_smile: