Transparency Occlusion Glitch

I made a test case to test out transparency and got some quirky results.





I have an application that has 2 quads and 2 capsules with blend states on them.

I saw an earlier post which related ( http://www.jmonkeyengine.com/jmeforum/index.php?topic=11488.0 )

so I made sure to have BoundingVolumes on everything yet I still get this weird state where sometimes the object is in front and sometimes it is behind. This inconsistent occlusion is bothering me.



What you see here is a simple change in camera angle, nothing on the Geometries has changed.

From one angle the scene looks a certain way, from a slightly different angle, the occlusion switches and it looks a different way.



The only difference between these screenshots is that I moved the camera a bit with the standard FPSInput  controls.







Is this a bug or, more likely, I’m betting I need to do some kind of manual manipulation of the Z buffer ?









:










Sounds for me like a zBuffer-Problem? Did you add one to your Nodes/Spatials?

If not try something like this:



ZBufferState buf = display.getRenderer().createZBufferState();
buf.setEnabled(true);
buf.setFunction(ZBufferState.TestFunction.EqualTo);
node.setRenderState(buf);

I think it's the same problem I had : http://www.jmonkeyengine.com/jmeforum/index.php?topic=7182.0



It's due to bucket sort wich use compare distances between camera and objects. So problem occured when objetcs are one in the other. That's why order change when you move camera.

Maybe you can provide your sourcecode so we could have a deeper look.

Check this page for info: http://www.opengl.org/wiki/Alpha_Blending

jME sorts transparent objects back-to-front, so that correct transparency is achieved. Unfortunately, under certain circumstances, this sorting can cause what you're describing. When two transparent objects are close to one another, and you move the camera to the side, the distance from one object will become closer to the camera and it will be drawn first, thus changing how the scene looks like.

RE: To adding the ZBuffer, that worked - sorta.



By adding a ZBufferState it makes the transparency of the objects consistent and it doesn't 'switch' occlusion while the camera is rotating, However, it did have one weird side effect, from the 'BACK' side the Quads are not visible, they appear fine and normal as the previous images from one side, while from another angle they pop off completely (see below)



This is the most important part of my code:


public void makeTransparent(Geometry target, float opacity)
   {
   
      //CullState cs = DisplaySystem.getDisplaySystem().getRenderer().createCullState();
      
      
        //Use some Z-buffer to allow multiple transparent objects to be stacked
        ZBufferState zbuf = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
        zbuf.setEnabled(true);
        zbuf.setFunction(ZBufferState.TestFunction.EqualTo);
        target.setRenderState(zbuf);
      // Make our quad transparent and assign the TextureState
        BlendState bs = DisplaySystem.getDisplaySystem().getRenderer().createBlendState();
        bs.setBlendEnabled(false);
        bs.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
        bs.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
        bs.setTestEnabled(true);
        bs.setTestFunction(BlendState.TestFunction.GreaterThanOrEqualTo);
        bs.setEnabled(true);
        bs.setBlendEnabled(true);
        target.setRenderState(bs);
       
      
      //set alpha factors for quads objects
      target.setSolidColor(new ColorRGBA(1, 1, 1, opacity));
      
      target.setLightCombineMode(LightCombineMode.Off);
      
      target.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
      
      target.updateRenderState();
      
      // make sure we have a bounding box!
      // without a bounding box the transparency only works from the 'Front'
      
      target.setModelBound(new BoundingBox());
      
      // The usual
      target.updateModelBound();
      
       
   }




Also, I have a VERY high Geomtry count in my real application, is applying a ZbufferState to all of these Geomtries a bad idea? (will it significantly reduce performance?) Or is it a better strategy to apply it to a Node that groups them? For instance, I have a Node that contains all the Quads in my scene

the last time i had transparency problems i just had to play a little (ok a lot) with all options on the ZBufferState and the BlendState untill things started to workout, try a little untill you get what you want.



about the performance i have no idea ;D

xopherxm said:

, However, it did have one weird side effect, from the 'BACK' side the Quads are not visible, they appear fine and normal as the previous images from one side, while from another angle they pop off completely (see below)


Try to add a CullState to the Quad so that no backface culling happens.


CullState cullState = display.getRenderer().createCullState();
cullState.setCullFace(CullState.Face.None);
cullState.setEnabled(true);



Or disable it.