In my game there is a Minecraft-like terrain made out of cubes. I generate a vertex buffer from the voxel data and use a texture atlas for looks of different blocks:
The problem is that the texture of distant cubes interpolates with adjacent tiles in the texture atlas. That results in lines of wrong colors between cubes (you may need to view the screenshot below at its full size to see the graphical flaws):
For now I use these interpolation settings but I tried every combination and even GL_NEAREST
without mipmapping doesn't provide better results.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
I also tried added an offset in the texture coordinates to pick a slightly smaller area of the tile but since the unwanted effect depends on the distance to the camera this cannot solve the problem completely. At far distances the stripes occur anyway.
How can I solve this texture bleeding? Since using a texture atlas is popular technique there might be a common approach. Sadly, for some reasons explained in the comments, I cannot change to different textures or texture arrays.
Answer
After struggling a lot with this issue, I finally came up with a solution.
To use both, a texture atlas and mipmapping, I need to perform the downsampling myself, because OpenGL would otherwise interpolate over the boundaries of tiles in the atlas. Moreover I needed to set the right texture parameters, because interpolating between mipmaps would also cause texture bleeding.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
With these parameters, no bleeding occurs.
There is one thing you have to notice when providing custom mipmaps. Since it doesn't make sense to shrink the atlas even if each tile is already 1x1
, the maximal mipmap level must be set according to what you provide.
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 7); // pick mipmap level 7 or lower
Thanks for all other answers and very helpful comments! By the way I still do not know how to use linear up scaling, but I guess there is no way.
No comments:
Post a Comment