[SOLVED] Two transparent colliding objects rendering order

Adding two transparent objects in the scene alternately prioritizes rendering order, while moving the camera near or far from it. Shown in this video: simplescreenrecorder-2023-01-19_14.17.34

Transparent “water” surface code:

        Geometry water = new Geometry("Water", waterMesh);
        Material waterMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        Texture waterTex = assetManager.loadTexture("Interface/Logo/Monkey.jpg");
        waterTex.setWrap(Texture.WrapMode.Repeat);
        waterMat.setTexture("ColorMap", waterTex);
        waterMat.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
        waterMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
        waterMat.setColor("Color", new ColorRGBA(1f, 1f, 1f, 0.58823f));
        water.setMaterial(waterMat);
        water.setQueueBucket(RenderQueue.Bucket.Translucent);

Shining light object code:

        Node worldLight = (Node) assetManager.loadModel("Scenes/shine.obj");
        
        Material lightMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        Texture lightTex = assetManager.loadTexture("Scenes/hmclight/lights.png");
        lightTex.setWrap(Texture.WrapMode.EdgeClamp);
        lightMat.setTexture("ColorMap", lightTex);
        lightMat.setTransparent(true);
        lightMat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
        lightMat.setColor("Color", new ColorRGBA(0.80392f, 0.76862f, 0.59215f, 1f));

        worldLight.setMaterial(lightMat);
        worldLight.setQueueBucket(RenderQueue.Bucket.Translucent);

There’s an option somewhere to fix this rendering bug but idk why or what it had caused, any ideas?

It’s not really a bug. There is no 100% correct way to sort transparent objects so that they work correctly. I can prove it with just two triangles.

In some case, you can trick sorting to always be correct for a particular set of geometry by forcing a fixed order. For example, always rendering the inside of a transparent cube before the outside. Or in your case, always rendering the floor before rendering the columns.

…but sometimes this isn’t even enough if the scene is more dynamic and you start to realize why games don’t have that many transparent objects in them.

This article talks about why the z-buffer is both friend and enemy in these cases:

1 Like

thanks for the answer, but how do i implement it in my code? what are the available methods for rendering with a fixed order?

You can implement your own geometry comparator… but then that has to handle sorting of everything.

Alternately, you can use a layer-based comparator like in Lemur.

(It’s registered automatically if you use Lemur and/or call Lemur’s GuiGlobals.initialize() method.)

That comparator will sort the normal way except when spatials are tagged with a “layer” value. In that case, the layer value is checked first… 0 being ‘farther’ than 1, etc…

LayerComparator.setLayer(floor, 0);
LayerComparator.setLayer(pillar, 1);

…would always render the floor before the pillar when in the transparent or translucent buckets (sorted back to front).

1 Like

No thanks, I just figured it out!

I’ll just change the water floor’s queue bucket to Transparent, and that sorta thing is gone.

Yes, because the transparent bucket is always rendered before the translucent bucket.

Your solution is fine until you need to use the transparent and translucent buckets for what they are actually meant for… or need more than two layers.

1 Like