I’m trying to load a complex model (a house), which have some transparent elements in it (window glass with an alpha of 0.5) and also some PNG textures with transparency in it (plants, decals of damages onto the wall etc …).
The model is made with Google Sketchup and i use Collada format to import.
The model loads well except the transparent elements:
Window glass is opaque
PNG’s transparent part is black
I suppose i have to change the bucket of the transparents elements, but what is the best method to do that ?
I see three possible way to do it :
Dividing the model into two models : one containing only opaque elements and one containing only transparent ones.
This is the method i want to avoid.
Setting a parameter during import of model or at the root node of it to tells JMe that this node contains transparent geometry which should be moved in transparent bucket.
Is it possible ?
Using a SceneGraphVisitorAdapter or something similar to detect myself the transparent elements or PNG textures and change by myself the bucket of it.
Is this method feasible ?
And also make sure that the model is set to “BlendMode.Alpha” under “AdditionalRenderState” in the material editor. Or if you edit your materials by code, use material.getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
@BigBob and @yaRnMcDonuts I already knew i had to properly set the getAdditionnalRenderState to make it works, i was just wondering if there was an automatic detection of transparent/transluscent materials and png in a loaded model.
So i followed the Graph Visitor approach as advised by @pspeed and it work’s !
Here is the minimal code if someone encounter the same issue:
public class TransparencyRepairer extends SceneGraphVisitorAdapter {
@Override
public void visit(Geometry c) {
if(c.getMaterial().getTextureParam("DiffuseMap") != null) {
if(c.getMaterial().getTextureParam("DiffuseMap").getTextureValue().getKey().getExtension().compareTo("png") == 0) {
c.getMaterial().getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
c.setQueueBucket(RenderQueue.Bucket.Transparent);
}
else if(c.getMaterial().getTextureParam("DiffuseMap").getTextureValue().getKey().getName().contains("Translucent")) {
c.getMaterial().getAdditionalRenderState().setBlendMode(RenderState.BlendMode.Alpha);
c.setQueueBucket(RenderQueue.Bucket.Transparent);
c.getMaterial().setColor("Diffuse", new ColorRGBA(1, 1, 1, 0.5f));
}
}
}
}
Notice that there is the word “Tranluscent” in my texture’s URL, this is how i detect which element should be transparent.
There’s a link in the header. I only know slightly more than that in truth but it becomes something one needs to understand the concept of once you start using transparent and translucent objects.
Translucent will render over everything as if you have depth write or depth test turned off… if you don’t have a special filter post processing setup. I use it all the time for this exact thing because it’s easy.
What it was designed for is the case where objects (especially transparent ones) needed to be rendered at a specific point in the filter post-processing pipeline… say for example if you needed something transparent rendered in line with the water filter.
In that case, for the translucent bucket to render properly then you need a translucent filter added to the post processor where you want that bucket rendered.
…else the translucent filter will just render over the top of everything as if depth has been cleared.
So, oxplay2 is right that Bucket.Transparent is probably what is needed in this case.
They are ordered as you thought. And without intervention, the translucent bucket is rendered exactly where filter post processing would be. If you have filtered post processing enabled then it may not be rendered at all.
This statement was essentially correct in the same way. You stated that it was incorrect.
The translucent bucket ignores depth, basically… unless it’s part of a filtered post processor change that has depth available.