Transparency weirdness

Started working on a mesh merger routine and as I set up a scene I noticed something.



I have 2 spheres and a cube. 1st sphere is at y 5, 2nd sphere at y -5 and the cube at y 0. Top sphere slowly moves down while the bottom sphere slowly moves up. Both spheres overlap halfway through then they move in the opposite direction.



Both sphere’s coloring is blue with 0.5f alpha.



Note that at this point there is no mesh merging going on, I just wanted to set a scene for this purpose.



Problem is:

When the test case starts, everything works fine, we can clearly see the cube between the spheres and the spheres moving in their respective direction. Although we can clearly see only 1 sphere is being drawn inside the other sphere (usually the top one portion).



If the camera looks upward the bottom sphere becomes fully opaque or if it is looking downward the top sphere becomes fully opaque.



If wireframe is turned on, we can clearly see the wires inside the other sphere (but not through the cube); but at the same time, as above, if the camera is looking up/down the wireframe loses it’s transparency.



I’ve tried many many different settings and ways to do things and the result is pretty much the same.



Is it me? Am I misunderstanding the result and/or what the result should be?



Thanks.



Here’s the test case:

[java]

/**

  • SphereMergeTest
  • @author MadJack

    */

    public class Main extends SimpleApplication {



    private Geometry sphere1;

    private Geometry sphere2;

    private float rate = .1f;



    public static void main(String[] args) {

    Main app = new Main();

    app.start();

    }



    @Override

    public void simpleInitApp() {

    Sphere sphere = new Sphere(30, 60, 5f);

    sphere1 = new Geometry("Sphere1", sphere);

    sphere2 = new Geometry("Sphere2", sphere);



    Material mat0 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    mat0.setColor("Color", new ColorRGBA(0, 0, 1f, .15f));

    mat0.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);

    mat0.getAdditionalRenderState().setColorWrite(true);

    mat0.getAdditionalRenderState().setDepthTest(true);

    // mat0.getAdditionalRenderState().setAlphaTest(true);

    mat0.getAdditionalRenderState().setAlphaFallOff(.5f);

    // mat0.getAdditionalRenderState().setWireframe(true);

    mat0.setTransparent(true);

    sphere1.setMaterial(mat0);

    sphere2.setMaterial(mat0);



    sphere1.setLocalTranslation(0, 5f, 0);

    sphere2.setLocalTranslation(0, -5f, 0);



    Box b = new Box(Vector3f.ZERO, 2, 2, 2);

    Geometry geom = new Geometry("Box", b);



    Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");

    mat.setColor("Color", ColorRGBA.Red);

    mat.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Off);

    mat.getAdditionalRenderState().setColorWrite(true);

    mat.getAdditionalRenderState().setDepthTest(true);

    geom.setMaterial(mat);

    rootNode.attachChild(geom);



    rootNode.attachChild(sphere1);

    rootNode.attachChild(sphere2);



    flyCam.setMoveSpeed(50f);

    }



    @Override

    public void simpleUpdate(float tpf) {

    float pos1 = sphere1.getLocalTranslation().y;

    float pos2 = sphere2.getLocalTranslation().y;

    if (pos1 > 5f) {

    rate = -rate;

    } else if (pos1 < 2.5f) {

    rate = -rate;

    }

    sphere1.setLocalTranslation(0, pos1 + rate * tpf, 0);

    sphere2.setLocalTranslation(0, pos2 + -rate * tpf, 0);

    }



    @Override

    public void simpleRender(RenderManager rm) {

    //TODO: add render code

    }

    }

    [/java]

I guess that’s a sorting issue.

That’s not a simple issue…the worst case scenario of transparency…a transparent object inside a transparent object.



You’d have to render the “inside” sphere before the “outside” sphere, but still it won’t be perfect you won’t see the “outside” sphere back faces through the inside sphere…



A way would be to render the back faces of the outside sphere, then the inside sphere, then front faces of the outside sphere…



That sounds overly complicated just for a test case for another purpose though…

@nehon said:
You'd have to render the "inside" sphere before the "outside" sphere, but still it won't be perfect you won't see the "outside" sphere back faces through the inside sphere....


The main problem here is that I get this behavior even if the spheres are not touching. As the camera looks upward, transparency on the bottom sphere goes away completely.

could you make screen shot because I don’t really get it

@madjack said:
The main problem here is that I get this behavior even if the spheres are not touching. As the camera looks upward, transparency on the bottom sphere goes away completely.


When you say "transparency on the bottoms sphere goes away completely"... do you just mean that you don't see objects through it (a transparent sort issue) or that the whole color noticeably changes to some different solid color?
@pspeed said:
When you say "transparency on the bottoms sphere goes away completely"... do you just mean that you don't see objects through it (a transparent sort issue) or that the whole color noticeably changes to some different solid color?


Not sure if this will be helpful, but I've hit similar issues with a single object and back faces. Some of the back faces seem to render as they should when others seem to make the object appear non-transparent. The banding is not uniform and I couldn't determine what the "deciding factor" for whether it displayed this way or not, as the "weirdness" areas changed as I rotated around the object.
@t0neg0d said:
Not sure if this will be helpful, but I've hit similar issues with a single object and back faces. Some of the back faces seem to render as they should when others seem to make the object appear non-transparent. The banding is not uniform and I couldn't determine what the "deciding factor" for whether it displayed this way or not, as the "weirdness" areas changed as I rotated around the object.


It is 100% the order that the triangles were drawn. 100%.
@t0neg0d said:
Not sure if this will be helpful, but I've hit similar issues with a single object and back faces. Some of the back faces seem to render as they should when others seem to make the object appear non-transparent. The banding is not uniform and I couldn't determine what the "deciding factor" for whether it displayed this way or not, as the "weirdness" areas changed as I rotated around the object.


And, by the way, that issue has a trivial fix: make the inside and outside separate objects so that you can force sort the inside to always be drawn first. For convex shapes where both inside and outside are drawn, this always works.

@pspeed

Here is a screen shot to show what I saw: Not sure how to separate the inside from the outside on a blender model… unless you mean to import it twice and cull it differently?



@t0neg0d said:
@pspeed
Here is a screen shot to show what I saw: Not sure how to separate the inside from the outside on a blender model... unless you mean to import it twice and cull it differently?




Sorry... I was still on the sphere kick.

In the case where it is one model that you've turned off face culling then you can just clone them and have one material with only front faces and one with only back faces. There will still be angles where things don't work right but it would be better in most cases. I have no idea what blender is actually doing in this case.

...and I think we are taking the original thread way off topic anyway.

Is that test case above not working for you guys? It was working fine here and very clearly shows the problem as described in my original and subsequent post.

I only have time and ability to look at what’s in the forum post, unfortunately. And sometimes a picture is worth a thousand words.

@pspeed said:
Sorry... I was still on the sphere kick.

In the case where it is one model that you've turned off face culling then you can just clone them and have one material with only front faces and one with only back faces. There will still be angles where things don't work right but it would be better in most cases. I have no idea what blender is actually doing in this case.

...and I think we are taking the original thread way off topic anyway.


So sorry... thought this was the same issue. Thanks a ton for the response!

There.



http://www.youtube.com/watch?v=1hCGPaVJx9E

Are your spheres in the transparent bucket?

that really looks like a sorting disorder, but even with the cube.

1 Like
@madjack said:
There.

http://www.youtube.com/watch?v=1hCGPaVJx9E



did you generate tangents for models?

[java]
TangentBinormalGenerator.generate(geom);
[/java]

Yeah, nehon is right.



Just add this.

[java]

sphere1.setQueueBucket(Bucket.Transparent);

sphere2.setQueueBucket(Bucket.Transparent);

[/java]

@mifth

No models are used. Only 2 spheres and a cube (shapes).



@nehon

No, it wasn’t. For some reason I forgot to do that.







Putting the shapes into the transparent bucket fixed the weird flickering.



The only other question is the way that only one of the sphere’s intersecting part is drawn. As shown in the pic below, only the bottom sphere’s intersecting (inside really) is showing through the top sphere. When the camera is moved to look downward the reverse happens. Since both materials have a 0.5f transparency technically both intersecting parts of the sphere should show through.



EDIT:

Forgot the picture. >.<



http://www.disenthral.com/files/transparency.png

that’s what i was saying in my first post.



You need to understand how transparency works. There is no such thing as a transparent pixel, you can just blend it with what’s already drawn.



transparent objects are drawn back to front so basically if you have opaque objects behind a transparent object you can it.



Now you have 2 transparent objects inside of one another…which one should be drawn first?

if it’s the one inside, you won’t see the back side of the one outside through the one inside (…not sure that’s clear)

if it’s the one outside you won’t see the one inside because it won’t be rendered because of the depth test.



you could disable depth test i guess in your case…but that’ll have other bad side effects.

@madjack said:
No models are used. Only 2 spheres and a cube (shapes).


Just add this to your code and you will be saved:

[java]

sphere1.setQueueBucket(Bucket.Transparent);
sphere2.setQueueBucket(Bucket.Transparent);
[/java]