Skip to content

J3MLoader always generates mips ignoring MinFilter #1882

@Ali-RS

Description

@Ali-RS

J3MLoader always set generate mips flag to true regardless of whether it is required by MinFilter or not.

for example, NearestNoMipMaps and BilinearNoMipMaps do not require mips.

/**
* Nearest neighbor interpolation is the fastest and crudest filtering
* method - it simply uses the color of the texel closest to the pixel
* center for the pixel color. While fast, this results in aliasing and
* shimmering during minification. (GL equivalent: GL_NEAREST)
*/
NearestNoMipMaps(false),
/**
* In this method the four nearest texels to the pixel center are
* sampled (at texture level 0), and their colors are combined by
* weighted averages. Though smoother, without mipmaps it suffers the
* same aliasing and shimmering problems as nearest
* NearestNeighborNoMipMaps. (GL equivalent: GL_LINEAR)
*/
BilinearNoMipMaps(false),

Shouldn't it check MinFilter and generate mips only if it is required?

Because of that, J3MLoader is broken, I noticed if I set the min filter to BilinearNoMipMaps on texture and export the material to a j3m file in the code then if I load it at runtime the min filter is set to Trilinear. It will work fine if I set it to something other than BilinearNoMipMaps.

That is because BilinearNoMipMaps is not written to the j3m file as it is the default min filter in the Texture class and is supposed to be used when nothing is specified for the min filter in the j3m file:

private MinFilter minificationFilter = MinFilter.BilinearNoMipMaps;

//Min and Mag filter
Texture.MinFilter def = Texture.MinFilter.BilinearNoMipMaps;
if (tex.getImage().hasMipmaps() || (key != null && key.isGenerateMips())) {
def = Texture.MinFilter.Trilinear;
}
if (tex.getMinFilter() != def) {
ret.append("Min").append(tex.getMinFilter().name()).append(" ");
}

but it does not work as expected because J3MLoader will set the mips generation flag to true and this causes TextureProcessor to change the min filter to Trilinear on texture when loaded with asset manager:

// enable mipmaps if image has them
// or generate them if requested by user
if (img.hasMipmaps() || texKey.isGenerateMips()) {
tex.setMinFilter(Texture.MinFilter.Trilinear);
}

If someone manually adds the BilinearNoMipMaps inside j3m file then it will work fine and will not get changed to Trilinear after loading but the generate mips flag will still be set to true.

Solution:

Those can be fixed by checking this inside the min filter and setting the flag only if it is required.

We would need to override the applyToTextureKey method :


            @Override
            public void applyToTextureKey(final String option, final TextureKey textureKey) {
                Texture.MinFilter minFilter = Texture.MinFilter.valueOf(option);
                textureKey.setGenerateMips(minFilter.usesMipMapLevels());
            }

inside

/**
* Applies a {@link com.jme3.texture.Texture.MinFilter} to the texture.
*/
Min {
@Override
public void applyToTexture(final String option, final Texture texture) {
texture.setMinFilter(Texture.MinFilter.valueOf(option));
}
},

forum post:
https://hub.jmonkeyengine.org/t/j3mloader-always-generates-mips-ignoring-minfilter-bug/46296

Metadata

Metadata

Assignees

Labels

bugSomething that is supposed to work, but doesn't. More severe than a "defect".

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions