Limit mipmap levels?

Hey guys,



Trying to enable mipmapping in my game, but having a tough time dealing with texture bleeding, as seen in the green band here:



http://i.imgur.com/HzRhJ.png



Is there a way to limit the number of mipmap levels, or another relatively easy way to deal with this? My texture map is pretty crammed, but I’ve tried increasing the texture “padding” without much luck. Increasing antroscopic filtering makes it thin green bands instead of a “haze”, which is an improvement… but not ideal.



Any suggestions? :confused:


  • Phr00t

I was reading something about mipmap bias – is there a way to set that in jMonkeyEngine?



http://www.opengl.org/registry/specs/EXT/texture_lod_bias.txt

Two possible solutiosn that worked for me so far,



either make the boarders of the atlas textues x times replicated, like have 3 times the boarder repeated, this reduces the effect.



The other solution would be to use a ArrayTexture instead of a TextureAtlas, depending on what you need as minimum requirements this might be unsuitable however.

Thanks for the suggestion EmpirePhoenix… both of those solutions are going to be pretty rough to implement :frowning:



I found by importing this:



[java]import org.lwjgl.opengl.*;[/java]



and using this function:



[java]GL11.glTexEnvf(GL14.GL_TEXTURE_FILTER_CONTROL, GL14.GL_TEXTURE_LOD_BIAS, -3);[/java]



I could change the bias, which gets rid of the problem. However, it gets rid of the problem by more-or-less disabling mipmapping… ho hum :frowning:

More discovered:



[java] GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LOD, 0f);

GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MIN_LOD, 0f);

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 0);

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_BASE_LEVEL, 0);[/java]



I found all these parameters; this one was described as:



GL_TEXTURE_MAX_LOD

Sets the maximum level-of-detail parameter. This floating-point value limits the selection of the lowest resolution mipmap (highest mipmap level). The initial value is 1000.



… which is exactly what I want. Unfortunately, these functions seem to do nothing, and I’m not sure why… anyone use these before, or have any ideas on how to use them correctly?



Thanks!

I guess they only work with pregenerate mipmaps like in dds, cause else the mipmaps are on the fly generated in the gpu.

These settings are applied per texture. You have to bind the ID first.

Is this feature useful enough that perhaps it should be added to core? What do you think?

@Momoko_Fan said:
These settings are applied per texture. You have to bind the ID first.
Is this feature useful enough that perhaps it should be added to core? What do you think?


How do I "bind the ID"?

I haven't gotten this to work to see how useful it would be... maybe if it was part of the core, I'd know :P I'd like to try this again!

Use glBindTexture(GL_TEXTURE2D, texture.getId())

Probably what you want is to have a single pixel per texture on the texture atlas. So if your texture atlas has 4x4 textures then the lowest mipmap level allowed should have a resolution of 4x4. However this still doesn’t fix the issue of the mipmap generator, which is blending adjacent textures together. You need a specialized mipmap generator that takes into account your texture atlas. In general I feel that getting texture atlases to work is quite difficult …

Thats why we have array textures :wink:



Btw if you only need a few textures, you might simulate a textureatlas, by just using multiple textures in the same material (always the same ones so the batching can take place) and use a additional texturecoordinate to select wich one it should be. Then you might reach the uniform limit (13) for a single material very quickly however.

I couldn’t find a Texture.getId()… I did find Texture.getImage().getId():



[java] TerrainTex = mainGame.getAssetManager().loadTexture(“Textures/terrain.png”);

TerrainTex.setMagFilter(Texture.MagFilter.Nearest);

if( Main.myForm.getSpecialEffects() ) {

TerrainTex.setMinFilter(Texture.MinFilter.NearestLinearMipMap);

TerrainTex.setAnisotropicFilter(8);

GL11.glBindTexture(GL11.GL_TEXTURE_2D, TerrainTex.getImage().getId());

GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LOD, 2f);

GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL12.GL_TEXTURE_MAX_LEVEL, 2);

…[/java]



… but it doesn’t seem to do anything :frowning: So how does array textures work? I’ve got about 64 textures for my terrain, but if you count the baked-in lighting system, it is 64*16 = 1024 textures :o



EDIT: I realized at this point, TerrainTex.getImage().getId() returns -1, which must mean it hasn’t been actually loaded yet(?). Later in my program, I assume after it has been rendered/loaded, it returns 10 – which then I assume these functions would work. Do I actually have to wait until it is rendered before setting these variables? Is there a way to load it ahead of time?



EDIT2: I just monitor the getId() result, and when it isn’t -1, I do the glTexParamter calls (then set a flag that this was already taken care of). The end result is, this really helps!