RenderQueue and transparency problem

I've been working on a "tracer round" object, which should just look like a long bright blur, to represent a bullet in a game.

I'm currently using a set of 4 Quads, arranged rotated around an axis by 45 degree increments, to make something that looks like this end on:

|/



/|



(Like an asterisk, if that doesn't make sense).



Each quad is textured with an alpha image, which is transparent apart from an oval blur in the center.

The problem I have is that with any setting I can find for AlphaState, TextureState, culling, RenderQueueMode, etc. I have some quads hiding the quads behind, even though they are "transparent". This is only visible from some angles, but is still very visible sometimes. The relevant code is:


      
      AlphaState alphaState = display.getRenderer().createAlphaState();
      alphaState.setBlendEnabled( true );
      alphaState.setSrcFunction( AlphaState.SB_SRC_ALPHA );
      alphaState.setDstFunction( AlphaState.DB_ONE_MINUS_SRC_ALPHA );
      alphaState.setTestEnabled(true);
      alphaState.setEnabled( true );
          
        rootNode.setRenderState(alphaState);
       
        lightState.setEnabled(false);
        rootNode.setRenderState(lightState);
       
       
      Texture bodyTexture = TextureManager.loadTexture(PlainShotMesh.class
            .getClassLoader().getResource("resources/plain_bullet.png"),
            Texture.MM_NONE, Texture.FM_LINEAR);

      TextureState ts = DisplaySystem.getDisplaySystem().getRenderer()
      .createTextureState();
      ts.setTexture(bodyTexture);

      for (int i = 0; i < 4; i++) {
         Quad q = new Quad("quad" + i, 1, 1);
         q.setRenderState(ts);
         q.setRenderState(alphaState);
         rootNode.attachChild(q);
         NodeRotator.rotate(q, 1, (float)(Math.PI/4d) * i);
         q.setRenderState(cull);
      }
      
      rootNode.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);

      rootNode.updateRenderState();
      rootNode.updateWorldData(0);



I've tried many other options. Interesting things I have found:

The default transparent queue ignores cull state (front, back, none) presumably because it overrides them for the two passes. This is a little confusing, it would be nice if it did the two pass render for stuff with cull state none, and just the appropriate pass for other states.

Setting display.getRenderer().getQueue().setTwoPassTransparency(false); makes cull states work for transparent objects, so it is possible.

I did think that the problem might be something to do with back facing quads, but culling them so I only see front facing ones, I can still see the problem

I would actually be able to cope without all this, since the textures can be drawn additively, so draw order doesn't matter, but even if I do that, I get quads hiding each other. I assume that the Z buffer is being used even when drawing the transparent stuff, which breaks quads that intersect. If the objects are already sorted, I think they should really be drawn using the z buffer from the opaque render pass, this way they will be occluded by opaque objects, but not by other transparent objects, but I'm not really an openGL expert, so I don't know if this is possible/makes sense.

I'm going to try having a look at the render queue code to see if what I just said makes any sense :)


EDIT: I checked, and that is what is happening. The z buffer is writable as the transparent objects are drawn, so they can hide each other. I assume this hasn't been spotted because normally the transparent object sorting handles this, but for my intersecting quads, it doesn't. If I attach a new z buffer state with setWritable(false) called on it, I no longer get the problem. It's just occured to me I could also break up the quads so that they are each a pair of quads on either side of the intersection, but I think the z buffer state is neater. Is this worth putting in as the default, or as a note in the render queue docs etc?

You mean make the Zbuffer of the ortho opaque pass unwriteable when drawing the distance sorted transparant objects? You could do that by giving all your transparant object (or the ones it’s important for) a different ZBufferState.



The stuff you say about cull states seems to make sense as well.

Yup more or less… It's not so much the ortho pass (I haven't got to the stage of testing it with my HUD yet) but rather the transparent pass itself. I can indeed fix it by setting a ZBufferState on the intersecting quads so they don't write to the z buffer, and so don't hide each other (or anything else that is sorted in front of them, but has sections behind them). I was wondering whether this might be a good default though, since the two pass code already messes about with the z buffer, etc. and it seems like having transparent objects always visible through each other is what the transparent queue is aiming to do, but at the moment it doesn't quite manage it for intersecting objects.



With the culling thing, looking at the render queue, it seems like it should be easy to make it respect cull states just by checking the state before overriding it, but I'm not familiar enough with the code to really say for sure, it still confuses me a little :slight_smile:

Uhm yes opaque of course.



I think what should be default is mostly a matter of preference… as long as you can change it with your own state (with one pass rendering). With two pass rendering it always uses the same type of ZBufferState (for the back), but I assume that's needed for it to work properly. However I'd think you are right it should not draw front and back if you have front or back culling enabled.