Help with blending images in the GUI node

I’m trying to blend the images in my gui node. I set the texture like this.

public void setTexture(Texture2D texture){
      material.setTexture("ColorMap",texture);
      material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
}

The gui elements will blend fine with any spatials in the scene but they won’t blend with the other elements in the gui node. I tried setting the quebucket to transparent/translucent for each spatial but they when I change the quebucket they disappear from the scene.

Here is a test picture.

As you can see the second monkey image is over lapping the first when I want them to blend. They blend fine with the gray blob in the background which is a cube but they don’t blend with other elements in the gui node.

Raise the Z coordinate of the one you want in front of the other

Yes, z controls the order in which transparent things are drawn. Draw order is the most important thing with transparency… Alpha/Transparency Sorting, Your Z-buffer, and You

Putting things in the guiNode is effectively putting them in the Gui bucket. If you put them in another bucket then they are no longer in the GUI and are back in the 3D scene.

The zorder isn’t the issue. If I raise the zOrder whatever element is on top renders completely over any elements behind it. Take a closer look at the monkeys in the image. The background of the monkey.png image is transparent. You can see it’s drawing over the second monkey where the transparent part should be. I already tried raising the zOrder assuming the two things on the same plain couldn’t blend correctly but that didn’t help.

It looks like the image is blending with objects in the root node but not applying the blend to the objects in the gui node.

P.S. That gray blob in the back ground is a cube geometry. It just looks like a box because I have the camera pointing right at it.

Then we need to see code… because I 100000000% guarantee you that this works fine if the z order is set properly.

I posted how I set the texture I thought that would be the only relevant part. However I did discover something else. The images blend fine in a test game. The only thing the test game has that isn’t in the editor is a sky box. I added a sky box and they blended fine.

With the sky box and on the same z plain.

With out the sky box and on the same z plain.

I’m not sure why but they render fine when the sky box is present. My only thought is something to do with the queue bucket. What part of the code would be relevant to this ? I’m not sure where to start looking.

Here is the image creation.

      Spatial spatial = new Geometry(name, new Quad(1,1));
      Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
      spatial.setMaterial(material);

The texture setter.

   public void setTexture(Texture2D texture){
      material.setTexture("ColorMap",texture);
      material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
    }

Then it’s added to the guinode. No other changes the material are made outside the creation and setting of the texture.

Put together a simple test case. It’s clear that our constantly saying “it’s a Z order problem” and the fact that 0% of your examples have shown setting the Z indicates to me that soda-straw views of your code is not going to be an effective means of fixing this issue for you.

So we will need to see ALL of the test case.

I did the simplest test possible and ran fine. This covers the way I create the image and set the texture. I can’t post my full source because this belongs to the Jpony package which has thousands of line of code. What else could mess the queue bucket and render order ? I rebuild the camera and add some filters. Could any of those things do that ? I really have no clue where to start looking. I already stepped through the image creation process and the bug isn’t in that so it’s coming from somewhere else. I’m just not sure what else would mess with render order.

package mygame;

import com.jme3.app.SimpleApplication;
import com.jme3.material.Material;
import com.jme3.material.RenderState;
import com.jme3.renderer.RenderManager;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.shape.Quad;
import com.jme3.texture.Texture2D;

/**
 * This is the Main Class of your Game. You should only do initialization here.
 * Move your Logic into AppStates or Controls
 * @author normenhansen
 */
public class Main extends SimpleApplication {

    Geometry image1;
    Geometry image2;
    Texture2D texture;
    
    Node test = new Node();
    
    public static void main(String[] args) {
        Main app = new Main();
        app.start();
    }

    @Override
    public void simpleInitApp() {
        // load texture
        texture = (Texture2D)assetManager.loadTexture("Textures/jmelogo.png");
        // create quads
        image1 = createQuad("1",image1);
        image2 = createQuad("2",image2);
        // scale and move quads
        image1.scale(100,100,1);
        image2.scale(100,100,1);
        image1.setLocalTranslation(300, 300, 1);
        image2.setLocalTranslation(350, 350, 1);
        // set textures
        setTexture(texture,image1);
        setTexture(texture,image2);
        
    }

    private Geometry createQuad(String name,Geometry geo){
        geo = new Geometry(name, new Quad(1,1));
        Material material = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        geo.setMaterial(material);
        guiNode.attachChild(geo);
        return geo;
    }
    
    public void setTexture(Texture2D texture,Geometry geo){
      geo.getMaterial().setTexture("ColorMap",texture);
      geo.getMaterial().getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
    }
    
    @Override
    public void simpleUpdate(float tpf) {
        //TODO: add update code
    }

    @Override
    public void simpleRender(RenderManager rm) {
        //TODO: add render code
    }
}

I found a fix for now.

    public void setDepthTest(boolean val){
      material.getAdditionalRenderState().setDepthWrite(val);
      material.getAdditionalRenderState().setDepthTest(val);
    }

Turning off the depth test works. I tried removing the filters and using the default cam settings but it had no effect. I’d still like to figure this out so I know for future references but at least for now I have a work around.

Facts we know now:
-simple test case works
-complicated code we can’t see doesn’t.

So it will be up to you to figure out what the difference is between the code we can’t see that doesn’t work and the code we can see that DOES work. We’ve been saying all along that it must be something in your code and now you’ve proved it.

Things to check:
-world location of the objects that are failing to blend properly
-material setup of the objects that are failing to blend properly
-bucket of the objects that are failing to blend properly

This is all presuming you aren’t messing with a different viewport or aren’t changing the geometry comparators and so on. That’s all in the code we can’t see.

Another approach, start adding things to your simple test case that your real app has until it breaks in a similar way.