Alpha Flickering

Ok, I know what you’re thinking. “Not another transparency thread!”. I’ve tried searching for this issue but haven’t found anything quite related to the issue I’m having with transparency.



The problem is, I have say 2 Quads both set to use a texture with transparency. I place the 2nd quad directly behind the first. Now, I ensure that the material has the proper blend mode and the quads are thrown into the transparency bucket. Now, the transparency works just fine…until the 2nd Quad (the one behind the first) starts to rotate.



I have modified the HelloMaterial example to reproduce this issue. Note the 2 quads in the center. If you move the camera to about say, 45 degrees or less to the surface plane of the Quads, you will see the alpha flicker effect. This effect has proven to be quite annoying and I’d love some advice on how to fix this, or if this really is a bug with jME3.



[java]

import com.jme3.app.SimpleApplication;

import com.jme3.light.DirectionalLight;

import com.jme3.material.Material;

import com.jme3.material.RenderState.BlendMode;

import com.jme3.math.ColorRGBA;

import com.jme3.math.Vector3f;

import com.jme3.renderer.queue.RenderQueue.Bucket;

import com.jme3.scene.Geometry;

import com.jme3.scene.Node;

import com.jme3.scene.shape.Box;

import com.jme3.scene.shape.Quad;

import com.jme3.scene.shape.Sphere;

import com.jme3.texture.Texture;

import com.jme3.util.TangentBinormalGenerator;



/** Sample 6 - how to give an object’s surface a material and texture.

  • How to make objects transparent, or let colors "leak" through partially
  • transparent textures. How to make bumpy and shiny surfaces. /

    public class HelloMaterial extends SimpleApplication {

    private Node node1;

    private Node node2;



    public static void main(String[] args) {

    HelloMaterial app = new HelloMaterial();

    app.start();

    }



    @Override

    public void simpleInitApp() {



    /
    * A simple textured cube – in good MIP map quality. /

    Box boxshape1 = new Box(new Vector3f(-3f,1.1f,0f), 1f,1f,1f);

    Geometry cube = new Geometry("My Textured Box", boxshape1);

    Material mat_stl = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    Texture tex_ml = assetManager.loadTexture("Interface/Logo/Monkey.jpg");

    mat_stl.setTexture("ColorMap", tex_ml);

    cube.setMaterial(mat_stl);

    rootNode.attachChild(cube);



    /
    * A translucent/transparent texture, similar to a window frame. /

    Box boxshape3 = new Box(new Vector3f(0f,0f,0f), 1f,1f,0.01f);

    Geometry window_frame = new Geometry("window frame", boxshape3);

    Material mat_tt = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    mat_tt.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png"));

    mat_tt.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); // activate transparency

    window_frame.setQueueBucket(Bucket.Transparent);

    window_frame.setMaterial(mat_tt);

    //rootNode.attachChild(window_frame);



    Quad quad = new Quad(1, 1);

    Geometry alphaQuad1 = new Geometry("Quad1", quad);

    Geometry alphaQuad2 = new Geometry("Quad2", quad);

    alphaQuad1.setMaterial(mat_tt);

    alphaQuad2.setMaterial(mat_tt);

    alphaQuad1.setQueueBucket(Bucket.Transparent);

    alphaQuad2.setQueueBucket(Bucket.Transparent);

    alphaQuad1.setLocalTranslation(-.5f, -.5f, 0);

    alphaQuad2.setLocalTranslation(-.5f, -.5f, 0);

    node1 = new Node("Node1");

    node2 = new Node("Node2");

    node1.setLocalTranslation(0, 0, 1f);

    node2.setLocalTranslation(0, 0, .95f); // place directly behind quad1

    node1.attachChild(alphaQuad1);

    node2.attachChild(alphaQuad2);

    rootNode.attachChild(node1);

    rootNode.attachChild(node2);



    /
    * A cube with its base color "leaking" through a partially transparent texture /

    Box boxshape4 = new Box(new Vector3f(3f,-1f,0f), 1f,1f,1f);

    Geometry cube_leak = new Geometry("Leak-through color cube", boxshape4);

    Material mat_tl = new Material(assetManager, "Common/MatDefs/Misc/ColoredTextured.j3md");

    mat_tl.setTexture("ColorMap", assetManager.loadTexture("Textures/ColoredTex/Monkey.png"));

    mat_tl.setColor("Color", new ColorRGBA(1f,0f,1f, 1f)); // purple

    cube_leak.setMaterial(mat_tl);

    rootNode.attachChild(cube_leak);

    // cube_leak.setMaterial((Material) assetManager.loadAsset( "Materials/LeakThrough.j3m"));



    /
    * A bumpy rock with a shiny light effect. To make bumpy objects you must create a NormalMap. /

    Sphere rock = new Sphere(32,32, 2f);

    Geometry shiny_rock = new Geometry("Shiny rock", rock);

    rock.setTextureMode(Sphere.TextureMode.Projected); // better quality on spheres

    TangentBinormalGenerator.generate(rock); // for lighting effect

    Material mat_lit = new Material(assetManager, "Common/MatDefs/Light/Lighting.j3md");

    mat_lit.setTexture("DiffuseMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond.jpg"));

    mat_lit.setTexture("NormalMap", assetManager.loadTexture("Textures/Terrain/Pond/Pond_normal.png"));

    mat_lit.setFloat("Shininess", 5f); // [0,128]

    shiny_rock.setMaterial(mat_lit);

    shiny_rock.setLocalTranslation(0,2,-2); // Move it a bit

    shiny_rock.rotate(1.6f, 0, 0); // Rotate it a bit

    rootNode.attachChild(shiny_rock);

    /
    * Must add a light to make the lit object visible! /

    DirectionalLight sun = new DirectionalLight();

    sun.setDirection(new Vector3f(1,0,-2).normalizeLocal());

    sun.setColor(ColorRGBA.White);

    rootNode.addLight(sun);



    }



    @Override

    public void simpleUpdate(float tpf) {

    super.simpleUpdate(tpf);



    // rotate quad2

    node2.rotate(0, 0, 3
    tpf);

    }



    }

    [/java]

Is it flickering or just switching sort as you move around? ie: is there a view you get to where sitting still it flashes? Or is it just that one sorts in front of the other “incorrectly” at some point?



See, transparency is all about the back to front rendering. Otherwise the Z buffer will get messed up. So if you draw the back quad first then it will obscure the front in the Z-buffer and so that part of the front one won’t get drawn. I can’t see any reason that they would sort badly in this case but I thought I’d clarify the behavior. There actually isn’t any universally correct way to sort shapes by Z but at a quick glance it looks like it would sort ok in this case.



Hmmm… I sort of remember having this problem once myself for a 45 degree surface. Can you try changing the lighting direction a little to see if it fixes it?

Yeah, I understand the concepts of z-buffer and transparency but this problem mystifies me. If you load the test class I supplied, you can see that once you move the camera to about < 45 degrees to the quads (moving closer to the quads allows you to see the flickering more clearly but not necessary). Even without moving the camera at all you can see the flicker effect. Changing the lighting direction makes no difference. scratches head

How did you change the lighting direction, ie: what to?

The quads in the example use the Unshaded material so lighting shouldn’t matter ?



I’m pretty sure the quads are being drawn in the wrong order when you see the flicker. If you put the quads in the Opaque bucket the issues goes away (well, the quads are always drawn in the correct order) so I would say it’s an issue with the order in which objects are rendered when in the Transparent bucket… Someone smarter will have to pick up from here :wink:

Yeah, it’s an Unshaded material so lighting doesn’t matter. I have no idea how to fix this though, so I’m willing to try anything. :slight_smile:



@pspeed

I tried all sorts of different angles for the light. Issue persists (which makes sense because as thetoucher pointed out, it’s an Unshaded material).

Then I got nothing. A flashing on and off when sitting still implies that a) the camera isn’t sitting still (probably not the case) or b) there is something with multipass lighting… which also isn’t the case.



I can’t think of any reason that the state would change from one frame to the next, otherwise.

Well thanks for helping to try to diagnose pspeed, much appreciated. Anyone else have any ideas? I’m stumped on how to fix this one as well.

Actually i have no such flickering.



What gui do you have? Intel by any chance?

The two quads are too close together… When you move to the side, the back quad gets rendered second, because jME3 thinks it is closer to the camera (one of its edges is closer, since it is rotated). Because its closer to the camera, jME3 has to render everything behind it so it blends with this quad, but it is wrong in your case because the front quad is still in the front.



The only way to fix it is to set your own transparent comparator that says that the front quad is always in the front, but of course you have to know the exact order things have to render otherwise it won’t work. Also you have to consider that the order can change if you look at the scene from the back rather than the front.

1 Like

But he says it’s flickering… like flashing even when the camera is standing still.



Unless my attempt at trying to clarify that failed outright.

the camera is still but the geometry behind is always moving (rotating)

@thetoucher said:
the camera is still but the geometry behind is always moving (rotating)


Ah, so it is a z sort issue as I originally suggested.

@Momoko

Wouldn’t it make sense for a Quad to be rendered based on its center and not on the various vertices? What you are mentioning makes sense why after about 45 degrees of viewing the Quad behind the first from the side causes the flickering because one point of the Quad might technically be closer…but if Quads are always sorted based on their center I don’t see how this issue could ever happen. I’ve played around with the test case I posted, but even moving at an angle from the bottom edge, I still see flickering…and all points of the 2nd Quad really are furthest away from the camera, so this doesn’t make sense.



To clarify, the flickering occurs regardless of whether the camera is moving or not. Once the camera is viewing the quads at <=45 degrees of incidence, the flickering occurs (because the 2nd Quad is rotating). I have effects in my game that rely on my Quads being rotated constantly and it’s annoying that when the camera gets to be certain angles from these Quads everything starts to flicker.

There is no perfect way to sort shapes based on Z. It’s not a solvable problem. JME currently sorts based on point closest to the camera of the bounding shape which can be better in many situations where a center point sort would not.



It’s exactly because there is no correct way to sort that I lobbied for and implemented the ability to set your own comparator. In some cases, I even use a comparator that allows me to bias the results with a value set on the geometry’s user data. In other cases, I do a straight material-based sort.



You could pretty easily set a comparator that sorted on object centers.

Interesting. Here’s an article on this topic as you just described pspeed.



http://www.sjbaker.org/steve/omniv/alpha_sorting.html



How would I go about defining my own Comparator for my Quads to use the center point? I think this would fix the issues I’m experiencing.

http://hub.jmonkeyengine.org/javadoc/com/jme3/renderer/queue/RenderQueue.html#setGeometryComparator(com.jme3.renderer.queue.RenderQueue.Bucket,%20com.jme3.renderer.queue.GeometryComparator)



And:

http://hub.jmonkeyengine.org/javadoc/com/jme3/renderer/queue/GeometryComparator.html



The current one for transparency is:

http://hub.jmonkeyengine.org/javadoc/com/jme3/renderer/queue/TransparentComparator.html



Hopefully you can work out how to get to the render queue for setting that. I can provide more hints if required.

Thanks pspeed for the input. I’ll have to give this a try, however…



I have been playing around more with the test case that I provided. If you move the camera directly towards the quads, stop, then just strafe left (move left) without changing the camera facing direction at all the flickering occurs. All vertices of the 2nd Quad (the rotating Quad) are behind the first and thus are furthest away from the camera at all times but yet the flickering occurs. How is this possible?

The distance between the quads is really small, while the distance when the 2nd quad rotates is much larger … If you move close enough on the Z axis and farther enough on the X axis the sorting will be wrong again

Also dont forget the limited z buffer depth, this can cause such flickering as well, when the frustum is set for rater large scenes(and has a very near nearestclip)