Seams at voxel boundaries and mipmap problem

Good day. I have a texture of 256x256, tile size is 16x16(Minecraft like). The screenshot below provides a fragment for a better understanding of the problems.

photo_2020-12-13_19-11-37

The problem are that seams appear at the voxel boundaries (in the screenshot below, the first problem is highlighted in red, and the second is highlighted in blue).
1- at magFilter (NarestFilter)
2- at minFilter(default - LinearMipmapLinearFilter)
The color of the seam matches the color of the subsequent texture in the texture atlas.

Regarding the first problem:
-The UV values ​​are not irrational, but these seams still appear. My understanding is that for any point in the texture that is not sampled exactly at the center of the texel, a linear sample is taken from 4 adjacent texels and calculates the value at the requested location as the average, which causes these seams to appear (evidence is that the color of these seams matches the color of the next texture).

So, one of the solutions, as I understand it, is extruding, but this is a “crutch”, my texture from a size of 256x256 will turn into a texture of 288x288 (which is not a power of two), there must be other ways, is there really no other solution? Maybe the best solution is to use some kind of texture array? But I think it’s expensive…

Regarding the second problem:
-I understand, I need to limit the number of mipmapping levels to 4, because 2 ^ 4 = 16 (tile size). If so, how do you do it? If this is not the case, then what …

Sorry for my English, I don’t speak it

This is a limitation of using a texture atlas like you’re using here. For WebGL1 I’m not sure if there’s a great solution outside of adding gutters between the tiles as you’ve suggested or writing a shader with custom mipmap sampling code.

For WebGL2 you can use a DataTexture2DArray which should allow you to sample one of the tiles based on an index variable and prevent bleeding between the tiles. You’ll still have to write a custom shader for that, though.

3 Likes

Since there is no other way, I will write my own shader, what can I do. Thank you for your responsiveness! I will mark with a decision how I will study the issue of texture arrays

1 Like

I used extruding and also set the NearestFilter property to NearestMipmapNearestFilter, this solved my problemScreenshot_11

What do you mean with “extruding”?

I most likely put it wrong. Now I will explain what I mean. So, the problem was that unwanted gaps appeared at the boundaries, and these gaps had the color of the neighboring texture, so the simplest solution was to take the UV not directly at the border, but by slightly shifting the UV inward. On the screen you can see red crosses - this is how I did before, and in green I marked how I am doing now, that is, the UV is taken not at the border, but slightly inward.
On the second screen you can see how this is implemented in the code.
Maybe this is not the best solution, but it helped, for now I will use it.
There was also a second way - to expand each texture by 1-2 pixels, these pixels would duplicate the color of the pixels on the border, but this does not suit me.

Screenshot_12

2 Likes

Hi @Azimov ,
Can you tell me how can I make like your image in the same face of the plane?

I dont understand your question

Thank you @Azimov , I want to know how can I send array of texture as shader uniform to fragment shader to show like your image.

Now I can send every texture with different key.

mipmap fixing: GitHub - mikolalysenko/voxel-mipmap-demo: Demo of mipmapping for voxel terrain
TextureArray, but not good, because use many if’s in shader, maybe webgl2 can use int fo texture number to delete if’s: https://codepen.io/illuminsi/pen/mdGYYmN
Voxel mesh optimization: Minecraft Mesh Toolbox (with colors)

1 Like