Anisotropic Filtering not affecting view?

In my game I have a car and some pink lines that follow tubes. My problem is that the lines (and the car’s orange stripe) seem to have the same blur regardless of the level of anisotropic filtering I apply.

This is what it looks like with anisotropic level 0:

And here it is with level 16 (as a new user I can only post one image, sorry): http://imgur.com/Sd1b1u1

The lines I don’t mind as much, but the orange stripe is painfully obvious. As I understand, anisotropic filtering is supposed to deal with this exact issue. You can see in the second image the printed output is saying the texture was a PNG, it’s initial filtering level is 0, and then it is set to 16.

If it helps, this game is targeted for android mobile right now, the tube texture is at 4096 and the car texture is at 2048. I don’t think they need to be so high, but I was unsure how to fix this issue. Am I misunderstanding something about anisotropic filtering?

Here’s the code:

@Override
public void simpleInitApp() {
AssetEventListener asl = new AssetEventListener() {
    public void assetLoaded(AssetKey key) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void assetRequested(AssetKey key) {
        if (key.getExtension().equals("png") || key.getExtension().equals("jpg") || key.getExtension().equals("dds")) {
             System.out.println(key.getExtension());
             TextureKey tkey = (TextureKey) key;
             System.out.println(tkey.getAnisotropy());
             tkey.setAnisotropy(16);
             System.out.println(tkey.getAnisotropy());
                
        }
    }

    public void assetDependencyNotFound(AssetKey parentKey, AssetKey dependentAssetKey) {
            //throw new UnsupportedOperationException("Not supported yet.");
    }
};

    
    assetManager.addAssetEventListener(asl);
    
    Spatial car = assetManager.loadModel("Models/rally_car/rally_car.mesh.j3o");
    Spatial tube_straight = assetManager.loadModel("Models/tube_straight/tube_straight.mesh.j3o");
    Spatial tube_turn = assetManager.loadModel("Models/tube_turn/tube_turn.mesh.j3o");

    AmbientLight lamp_light = new AmbientLight();
    rootNode.addLight(lamp_light);
    rootNode.attachChild(tube_straight);
    rootNode.attachChild(tube_turn);
    rootNode.attachChild(car);
}

Thanks guys.

I don’t have the link at hand but try to play around with the “Texture Filtering” (MIN, MAG Filter).
I’d say this will fix your issue (It will sharpen the textures), whereas anisotropic filter would only effect odd winkels.

Also feel free to use the Engine Verson 3.1 as it includes lots of fixes.

So I gave the texture filtering a shot. Strictly for the car, here is what I did, after loading the car .j3o model:

Texture tex  = assetManager.loadTexture("Textures/rally_car/base_color.png");
    tex.setMagFilter(Texture.MagFilter.Bilinear);
    tex.setMinFilter(Texture.MinFilter.Trilinear);
    
    System.out.println("LEVEL: " + tex.getAnisotropicFilter());
    System.out.println("LEVEL: " + tex.getMagFilter());
    System.out.println("LEVEL: " + tex.getMinFilter());

Unfortunately, the results didn’t look any different:

I can try playing with other filtering settings. Was my method of setting the car’s texture settings correct? I’m not sure if just getting the texture without any reference to the j30 model is actually changing the texture as it applies to the model. Thanks for the help.

No that’s wrong.
You should do it exactly as you did with anisotropic filtering.

Also see here and the following posts:

Are you loading a material file?

@Darkchaos But how? I set the anisotropy via the texture key, but you can’t set the mag filter like that. I’d have to:

Texture tex = assetManager.loadTexture(tkey);
tex.setMagFilter(Texture.MagFilter.Bilinear);

but doing that in the listener causes a StackOverflow execption. I don’t see how the fellow in the other thread fixes it.

@JESTERRRRRR no material file is loaded manually, the model is a j3o converted from an ogre mesh file, which also had an ogre material file and a texture with it.

a) You should use “if key instanceof TextureKey” instead of checking the extension
b) It’s usual to have a stack overflow, see: You try to load a texture which leads to assetRequested() which loads a texture…

Try to do something in assetLoaded, maybe something like key.getData() or whatever is there.

The alternative is using http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:traverse_scenegraph with something like this in the visit:

if (spatial instanceof Geometry) {
  Geometry geo = (Geometry)spatial;
  geo.getMaterial().getTexture().setMinFilter()
}

Note: I didn’t check the code and don’t remember if it works to get the texture like that, but it should be easy for you to work it form there.

Alright, so you are right, your code didn’t work right off the bat :confused:

However, I ran with it, and got to here:

Geometry car_geo = (Geometry)((Node)car).getChild(0);
Material mat = car_geo.getMaterial();
System.out.println(mat);
Texture tex = mat.getTextureParam("").getTextureValue();
tex.setMagFilter(Texture.MagFilter.Bilinear);
tex.setMinFilter(Texture.MinFilter.Trilinear);

Now my problem is that I have no idea what the param is in getTextureParam. I tried “ColorMap”, but that returned a nullPointerException. What should the param be?

Ohhhh, so you really meant for any spatial. I wasn’t sure if that was just a code sample you gave for the convenience. I’ll try Nearest and let you know. Thanks for being patient and responsive :sweat_smile:

1 Like

Also try Nearest as Mag Filter (as suggested in the Post I linked)
Also your code is really different than what I suggested: My code will apply this to any Geometry under a given parent.
Your code only works for the current structure of your car and will crash the game when the first child isn’t a Geometry any longer.

However It is good to do some testing :smile:
Also note that appart from the DiffuseMap there could be some additional Alpha Map and stuff (but that isn’t so important than the Diffuse (which is the ColorMap))

Alrighty. Now I’ve implemented a scene graph traversal, and at every spatial I’m doing what I did above, if it happens to be a geometry( and in Mag I have Nearest)>

It seems … it doesn’t seems to change anything.

Here’s the code so far, just so that I’m not really screwing anything up:

@Override
public void simpleInitApp() {
    
    AssetEventListener asl = new AssetEventListener() {
       public void assetLoaded(AssetKey key) {
            //throw new UnsupportedOperationException("Not supported yet.");
       }

       public void assetRequested(AssetKey key) {
            if (key instanceof TextureKey) {
            
                TextureKey tkey = (TextureKey) key;
   
                tkey.setAnisotropy(16);
                
                System.out.println(tkey.getAnisotropy());
                
           }
        }

        public void assetDependencyNotFound(AssetKey parentKey, AssetKey dependentAssetKey) {
            //throw new UnsupportedOperationException("Not supported yet.");
        }

      
    };

    
    assetManager.addAssetEventListener(asl);
   
    
   
    Spatial car = assetManager.loadModel("Models/rally_car/rally_car.mesh.j3o");
    Spatial tube_straight = assetManager.loadModel("Models/tube_straight/tube_straight.mesh.j3o");
    Spatial tube_turn = assetManager.loadModel("Models/tube_turn/tube_turn.mesh.j3o");
    
    SceneGraphVisitor visitor = new SceneGraphVisitor() {

        @Override
        public void visit(Spatial spat) {
          // search criterion can be control class:
          if (spat instanceof Geometry) {
            Geometry geo = (Geometry)spat;
            Texture tex = geo.getMaterial().getTextureParam("DiffuseMap").getTextureValue();
            tex.setMinFilter(Texture.MinFilter.Trilinear);
            tex.setMagFilter(Texture.MagFilter.Nearest);
          }
          
        }

    };


           
    
    AmbientLight lamp_light = new AmbientLight();
    rootNode.addLight(lamp_light);
    rootNode.attachChild(tube_straight);
    rootNode.attachChild(tube_turn);
    rootNode.attachChild(car);
    
    rootNode.breadthFirstTraversal(visitor);
}

Code wise it looks good but I’m not an expert in these things.

What do you think:
Before:
https://hub.jmonkeyengine.org/uploads/default/original/2X/4/404ee5b9c7b4e8cf1c202a7a05d67e52a5b3767c.png

After:

This looks like your issue?
Oh and also set the MinFilter to Nearest or whatever possible (try multiple settings).

The reason is this: The MagFilter defines what happens when a Small Texture is being upscaled and the MinFIlter when it’s being downscaled (so how one pixel is made up of multiple texels and vice versa)

Oh I got it! Thank you! I had to set the Min Filter to Nearest, and it made everything crisp. I guess using the most advanced algorithm had it sampling around and blurring it (or something). I really appreciate the help, going back and forth over the course of the day. I learned a tremendous amount.

1 Like