Transparency: Objects are not Visible behind Transparent Walls

Hi Everybody,



First: I read a lot about Transparency in this forum and tried different ways to fix this problem but i haven’t found a solution yet.



I’m using JMonkey now for about 4 Months so I don’t know all details about it.



But now to my Problem:

I wrote a Converter for Train Simulator Shape Files this Weekend having some Troubles with the Transparent and Translucent parts of the Textures.



Because the hole Converter is to big to post here, i tried to load a .3ds file and remarked that i have the same problem there.

Here are two images to explain:



This is an image from outside the car. As you can see on the left side, there are missing some chairs. If I rotate the camera on the other side of the car, the visible chairs become invisible an vice versa.



For better understanding I give you a picture from inside the car:





The important code i use is the following:


            //Set up Alpha states
            BlendState as= this.getRenderer().createBlendState();
            as.setBlendEnabled(true);
            as.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
            as.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
            as.setTestEnabled(true);
            as.setTestFunction(BlendState.TestFunction.Always);
            as.setEnabled(true);

            ZBufferState z = DisplaySystem.getDisplaySystem().getRenderer().createZBufferState();
            z.setEnabled(true);
            z.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
            rootNode.setRenderState(z);
            rootNode.updateRenderState();

            //now load the Model (this is a seperate methode which calls the MaxToJme-Converter)
            vehicle = loadModel("Models/EW_IV/EW_IV_B.3ds");

            vehicle.setRenderState(as);
            vehicle.updateRenderState();



I hope you can help me and i haven't forgotten to read an important article :wink:

David



You have to call setRenderQueueMode(Renderer.QUEUE_TRANSPARENT) on all transparent Spatials.

Also the correct alpha test function should be GreaterThan:

as.setTestFunction(BlendState.TestFunction.GreaterThan);

I inserted the following line:

 
               vehicle.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);


And nothing changed.

The transparent parts come from an alpha channel in .tga picture. So I don't have complete translucent Spatial's.
By the way: What is the equivalent Statement for a TriMesh (because in my ShapeConverter I'm using TriMeshes to create the Geometry).

Yeah, I tried to change the TestFunction to GreatherThat but this didn't help at all.

With translucent objects you should usually disable zbuffer writes also with something like


z.setWritable(false);



However I think your problem is that the whole thing is one model?
This will cause a problem because the transparent render queue and the zbuffer write disable really need to be applied to the transparent part only. If the whole thing is in the transparent render queue, then it won't work properly - the point of that queue is to make sure transparent stuff is drawn after the other stuff.

The Model you see in the images is a .3ds model which is loaded by the MaxToJme converter. Takig your statement: does that mean that the converter doesn't care about transparency?



And the other thing: supposing that every little part of the car has a piece which is transparent/translucent (defined by the Alpha Channel of the Texture), can in this case the car be drawn correctly?

Important: In this application there are almost never hole Spatials which are completely transparent/-lucent (only one piece which is defined by the Alpha Channel of the Texture).

Well I don't have a complete understanding myself.

In short, I think it will handle your partially transparent stuff fine, but probably not having a partially transparent object and the things on the other side it all in the same mesh.



As I understand it though, the way the transparent render queue works is that anything in there is not drawn till after all the opaque stuff has been. So for example, when you draw the window it assumes that anything you can see through the window is already there, and it just blends on top of that.



If it's all in one object through, that assumption falls down. It would have to depth sort every triangle before it rendered it or something to know what to draw first.



If you could at least separate it into exterior and interior meshes, it should work a lot better. Depending on how you had it set up in max, it may well already be that way - in which case you just need to identify the transparent bits and only put those in the transparent render queue.

Ha, i get one step forward:

I inserted the folowing line:

            as.setReference(0.5f);


and now I can see all I need. But the parts which should only be translucent are now transparent.
This is much better but not the solution I like most.
Here a screenshot:

That's alpha killing, a different approach to the alpha sorting problem. That way the depth buffer can be utilized to determine what to draw in front of what, because no blending is done.

You'll have to do what Alric suggests if you need blending (split up the model so the parts that will have to be blended in any camera angle can be properly depth-sorted).

Alric, your understandings about alpha blending and depth sorting are all correct, btw.

I try to repeat in my words what you mean (just to be sure that I understood you):

I have to make multiple meshes (i.e. for every Chair an own TriMesh).



If you  meant that: That's what you can see in the screenshot. Every Chair is an own TriMesh which is "grouped" in a Node for the internal.

Then the railcar body is one TriMesh (the Red walls) and the interior Walls are also in a separate TriMesh. The Structure is (depends on the Model):



                            Outside Body

            Body ---- Inside Body

Main —

            Bogie1— Wheels1

                          Wheels2





I hope i wrote it more or less understandable.

The Structure of this Model is given (because i read a Microsoft Train Simulator Shape File) but in the end the Model consists a lot of TriMeshes which all can have some parts in their Textures which need blending.



I hope i understood you right :wink:



Dave

You have to create on TriMesh for each window. The windows can be transparent texture. Then you must remove the alpha channel on the train texture to make it opaque. Then it should render perfectly.

The Problem is, that I only load (not create) the Models so in fact i have no idea which part in the file represents a window.

This means i should be able to identify the translucent parts in the Texture then match them to their 3D Part und create a seperate Object for them.



So is my next Question: How can I identify the transparent parts in a Texture?

rhbdavid said:

The Problem is, that I only load (not create) the Models so in fact i have no idea which part in the file represents a window.
This means i should be able to identify the translucent parts in the Texture then match them to their 3D Part und create a seperate Object for them.

This will be very difficult, if not impossible.

Another way would be to render the transparent objects twice. First setup alpha test so that only the opaque part is rendered. This is what you did when you set the reference value. Then setup alpha test so that only the transparent part is rendered. You will probably have to mess with multipass rendering to get the order right. You'll also have to clone or load the model twice in order to render it twice.

Btw, I feel you're pain. Transparency is a mess if you don't have control over the model.

I love you for this Idea :lol:



I think it could slow down the hole thing if I load a hole train like that but I think it’s enough just to load one ore two vehicles near the camera (I’ll think about that later).



Here a screenshot of a car (I took another one to show the effect):





Thank you very much for your endurance with my problem.



Dave