Depth sorting

Hey there,



I have many flat geometries. Lines, Quads with partially transparent textures, and such. And they are all in one plane at a certain distance from the camera.



They can be devided into three categories: A, B and C.



A geoms have to be drawn in front of B geoms.

B geoms have to be drawn in front of C geoms.

C geoms have to be drawn in front of A geoms.



See the problem?



Can I solve this with ZBufferState alone? how? any other ideas?



tanks in advance,

Andy

If you're using the ortho render queue you can use the method Spatial.setZOrder() to set the ordering.

dhdd said:

A geoms have to be drawn in front of B geoms.
B geoms have to be drawn in front of C geoms.
C geoms have to be drawn in front of A geoms.


I am a little tired now, but is this even possible?

Now that I think of it there's a way to do it with the opaque queue as well. Have 3 render passes, 1 for each type of geometry, then use polygon offset on the pass that will decrease Z in order of the pass. It's definitely possible, Haladaria, as long as you know your depth buffer stuff.

It confused me too - unless all three can never overlap.

If an A is in front of a B, then where do you put a C? It can't be both in front of the A and behind the B?

Hevee or hamster would be good to consult - they have ccolusion tests - of course only really good when the scenegraph is threaded

Momoko_Fan said:

Now that I think of it there's a way to do it with the opaque queue as well. Have 3 render passes, 1 for each type of geometry, then use polygon offset on the pass that will decrease Z in order of the pass. It's definitely possible, Haladaria, as long as you know your depth buffer stuff.


If they all can overlap, then we have the following depths:
a < b
b < c
c < a 
But the last will be a contradiction because we already know from the first two that a < b < c which forces a < c!

thanks guys.



i went with the renderpasses (and their order of drawing) plus zbufferstates and a little hack … complicated but seems to work  :wink:

I'd love to see some details of your solution, any maybe even a little demo class to see what it looks like - do you think either would be possible?

well i have to disappoint you because the solution is much simpler than expected:



i changed the requirement ( i know i shouldn't  ;)) that said all three classes have to be in one plane so i just set the ZBufferStates appropriately.



A, B and C quads are all in seperate RenderPasses and rendered in that order:


  • B is rendered normally with standard zbufferstate
  • then A is rendered with TestFunction.Always but its actually slightly further away than B (0.0001f) (A is rendered in front of B)
  • C is rendered normally with standard zbufferstate and its z value is between B and A (C is rendered in front of A but behind B)







    i cannot give you code examples because of the variable names everyone would know what i am working on and thats not allowed to happen in the company i work.  :expressionless:



    i hope i described it well enough for you to know what i am doing.  :wink:

Can't get it to work :frowning: have I misunderstood something?


    protected void simpleInitGame() {
        lightState.setEnabled(false);
       
        Pass aPass = new RenderPass();
        Quad a = new Quad("A", 5, 5);
        a.setDefaultColor(ColorRGBA.red);
        aPass.add(a);

        Pass bPass = new RenderPass();
        Quad b = new Quad("B", 5, 5);
        b.setLocalTranslation(2f, 3f, 0);
        b.setDefaultColor(ColorRGBA.green);
        b.setLocalRotation(new Quaternion(new float[]{0, 0, FastMath.PI/3f}));
        bPass.add(b);

        Pass cPass = new RenderPass();
        Quad c = new Quad("C", 5, 5);
        c.setLocalTranslation(-3f, 2.5f, 0);
        c.setLocalRotation(new Quaternion(new float[]{0, 0, -FastMath.PI/3f}));
        c.setDefaultColor(ColorRGBA.blue);
        cPass.add(c);
       

        ZBufferState standardZBuf = display.getRenderer().createZBufferState();
        standardZBuf.setEnabled(true);

        ZBufferState specialZBuf = display.getRenderer().createZBufferState();
        specialZBuf.setEnabled(true);
        specialZBuf.setFunction(ZBufferState.TestFunction.Always);


//- B is rendered normally with standard zbufferstate
        pManager.add(bPass);
        b.setRenderState(standardZBuf);

//- then A is rendered with TestFunction.Always but its actually slightly further away than B (0.0001f) (A is rendered in front of B)
        pManager.add(aPass);
        a.setRenderState(specialZBuf);
        a.getLocalTranslation().add(0, 0, 0.0001f);

//- C is rendered normally with standard zbufferstate and its z value is between B and A (C is rendered in front of A but behind B)
        pManager.add(cPass);
        c.setRenderState(standardZBuf);
        c.getLocalTranslation().add(0, 0, 0.00005f);
    }

i cant try it myself right now but let this have a go:



//- B is rendered normally with standard zbufferstate
        pManager.add(bPass);
        b.setRenderState(standardZBuf);

//- then A is rendered with TestFunction.Always but its actually slightly further away than B (0.0001f) (A is rendered in front of B)
        pManager.add(aPass);
        a.setRenderState(specialZBuf);
        a.getLocalTranslation().add(0, 0, -0.0006f);

//- C is rendered normally with standard zbufferstate and its z value is between B and A (C is rendered in front of A but behind B)
        pManager.add(cPass);
        c.setRenderState(standardZBuf);
        c.getLocalTranslation().add(0, 0, -0.0003f);



of course it also matters from which side (z-wise) you look at it. i'll try to make that test work tomorrow myself  ;)