Search code examples
openglglsllwjgl

How to Get Rid of Tiling Borders When Mipmapping is Disabled


I created a fragment shader that tiles a texture (it is actually a texture array, as you will see in the code). However, I get very ugly 1 pixel borders around each of the tiles. I know this can be caused by discontinuity of the function, causing weird stuff to happen while mipmapping, but I have mipmapping disabled (although I am using antialiasing). Here is my code:

vec2 tiledCoords = fract(pass_textureCoords * 256.0) / 4.0; // pass_textureCoords are the texture coordinates

out_Color = texture(testArray, vec3(tiledCoords.x, tiledCoords.y, 0)); // testArray is the sampler2DArray

I thought I'd have to give a bit of tolerance for rounding errors, but I can't seem to figure out where to put that. How can I get rid of these ugly borders? Thanks in advance!

Here is a screenshot: Ugly lines


Solution

  • I'm not exactly sure what you are trying to do with the calculations in your code. The first line doesn't seem to contribute to the result at all (is overwritten in the second line). Since you didn't set filter modes or wrap modes, you'll have the default settings enabled which is linear filtering and repeat mode.

    It seems that you are using tiledCoords in the range of [0, 0.25] and try to wrap from 0.25 to 0. Linear filtering is not going to work automatically in this case since there is no automatic wrap mode for the 0.25 -> 0 transition. The black lines are cause from the linear interpolation in the range [0, 1/(2 * num_pixels)] because this area interpolates linearly between the 0th texel and "-1st" texel (which is due to wrapping mode the last texel of your texture). Same thing happens for the range [0.25 - 1/(2 * num_pixels), 0.25] where you interpolate the pixel directly left of texture coordinate 0.25 with the texel right of it.

    There is no way to get hardware linear interpolation for your scenario. You can either use nearest neighbor sampling or calculate linear interpolate manually.