From my understanding of what Iāve read so far about transparency here, when intersecting transparent objects meet, the depth is determined from the geometry and not from the vertex being drawn? This would bring the problem weāre seeing, I think.
Depth is determined per pixel and drawn into the depth buffer if the depth test succeed.
This is the case of course if depth write and depth test are enabled.
whatās depth test : the depth of the pixel being drawn is compared to the depth already in the depth buffer, if the pixel depth is higher than the one in the depth buffer, the pixel is not drawn ( in human language, the pixel is behind whatās already drawn)
whatās depth write : the fact of writing the depth value of a pixel in the depth buffer.
Transparent bucket is sorted back to front. The sorting does take into account the object position (z position in the view)*
so basically in your case,from the screen shot. The bottom sphere is drawn before the top sphere, and looks correct.
Then the top sphere is rendered over it but the part of the top sphere inside the bottom sphere fail the depth test and is not rendered.
Thatās why you donāt see the bottom of the top sphere.
If you disable depth test for the sphere itās gonna be correct. BUT!!! it wonāt be correct anymore with the cubeā¦
What Iām saying is that there is no real solution to your problem.
I was toying with an idea a while ago for a multi value (two step) rendering process. That would solve this but the overhead might be an issue.
Essentially rather than a single screen and z buffer you have a configurable number (3 might even be enough for most cases but that would need testing).
For each pixel you store the rgbaz value at each layer.
When writing a new pixel (Pseudo code):
[java]
Check z against layer 0, if behind {
discard.
} else if (new a is 1) {
remove all layers with z behind new z and shuffle any remaining down.
write rgbaz to layer 0.
} else {
find z position in layers (use lowest empty layer if empty)
insert value to layer, shuffle other layers up
if (not enough layers) {
find the least contributing layer (by multiplying the inverse alphas of every layer above it and its own alpha)
remove that layer (merging with layer behind it)
}
}
[/java]
Finally once the main rendering step is complete collapse all the layers together by a simple merge - draw each layer one at a time on top of layer 0 until all have been processed.
Advantages:
Handles intersecting transparency much better (flawlessly unless more than X transparent objects all intersect each other, and even then it degrades gracefully).
No need to pre-sort transparent objects or handle them separately from opaque ones.
Will cope with the cases listed above perfectly (as itās handling the depths on a per pixel bases not per object).
Disadvantages:
Larger screen buffers needed and extra processing in the render step + the extra final step (although that would be very fast).
Just an idea I had knocking around in my head so thought Iād throw it out there
But if i switch TestDepth off i get correct transparency but i have no depth at all.
My code:
[java]
reactorEffect = app.getAssetManager().loadModel(āModels/FakeParticleBlow/FakeParticleBlow.j3oā);
reactorEffect.rotate(FastMath.HALF_PI, 0.0f, 0.0f);
// GeometryBatchFactory.optimize((Node)reactorEffect);
Material mat2 = new Material(app.getAssetManager(), āMatDefs/FakeParticleBlow/FakeParticleBlow.j3mdā);
mat2.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Additive);
mat2.getAdditionalRenderState().setAlphaFallOff(0.01f);
mat2.getAdditionalRenderState().setFaceCullMode(RenderState.FaceCullMode.Off);
It looks like the part towards you is getting rendered first and then stopping the higher opacity part in the center getting rendered.
Option 1: Leave Depth test on, turn off depth writing.
Option 2: Change the engine trail model to be a single polygon instead of the existing set. Keep the polygon sticking out from the ship on 2 axis but spin it around the 3rd to always face the camera (sort of like a constrained billboard).
I did some kind of hack. It fixed my issue.
I created j3m file and wrote with text āDepthTest Falseā for additional render state. Then I set in the code:
[java]mat2.getAdditionalRenderState().setDepthTest(true);[/java]
AND MIRACLE! It works like i want! @madjack i know this is old post but can you test it like i did? just create j3m material and set āDepthTest Falseā. And then set DepthTest True in your code for the material.
@nehon it seems you have a bug it the depth. But it works some kind.
I think you have probably just stumbled onto a way to make option 1 work. Depth test true with depth write false is definitely what you want for this material. Maybe there is some bug with that and the way youāve done it in the j3m file + code works around it somehow.
@mifth It will look fine from all angles, thatās what the rotation is for. The only thing that might look slightly better with your version is if you are looking nearly straight at the engine from behind, but even in that case the difference will be tiny and the trail will be wiped out by the glow from the engine itself anyway.