Hi,
I know it is not easy to render transparent object in opengl in the correct order. But a simple improvement is to render the scene twice.
In the first pass render only all nontransparent object. In the second pass render all transparent objects. This solution didn't solve the problem with more transparent objects behind each other. But its good enough for the most use-cases with few transparent objects. A transparent object and a nontransparent object always appear in the correct order.
thx
Better transparency with JOGL-Backend
Re: Better transparency with JOGL-Backend
Yes you are right. The problem with this approach is that "transparent" and "non-transparent" are not well-defined. If the geometry has vertex or face colors, then the alpha channels of these colors will also effect the transparency of the geometry. And, the alpha channel of a texture also contributes to the transparency. So, it's not enough to simply test the transparency settings in the appearance in order to determine whether the current geometry is "transparent" or not.
One could render twice, based on whether the "transparencyEnabled" flag is false (first pass) or true (second pass). I hadn't thought of that, it would probably be a useful alternative. But right now I don't have time to do anything in that direction.
One work-around as you probably know is to arrange your scene graph so that all transparent objects come after all non-transparent objects in the scene graph. I know it's not always possible but for many applications it does work well.
Long term we would like to implement something called "depth-peeling" for the JOGL backend; its a vertex shader that renders the scene multiple times, each time adding one more layer of geometry in the depth direction. See http://developer.download.nvidia.com/SD ... eeling.pdf. Any volunteers to implement it?
One could render twice, based on whether the "transparencyEnabled" flag is false (first pass) or true (second pass). I hadn't thought of that, it would probably be a useful alternative. But right now I don't have time to do anything in that direction.
One work-around as you probably know is to arrange your scene graph so that all transparent objects come after all non-transparent objects in the scene graph. I know it's not always possible but for many applications it does work well.
Long term we would like to implement something called "depth-peeling" for the JOGL backend; its a vertex shader that renders the scene multiple times, each time adding one more layer of geometry in the depth direction. See http://developer.download.nvidia.com/SD ... eeling.pdf. Any volunteers to implement it?
jReality core developer
Re: Better transparency with JOGL-Backend
Depth-peeling seems to be a cool feature. But until then i tried to implement the easy way ;-)
Maybe it could help for future releases of jReality:
Maybe it could help for future releases of jReality:
Code: Select all
//JOGLRenderer.java
public class JOGLRenderer {
public boolean renderTransparency = false;
public int skipedGeometryCount=0;
...
private void renderOnePass() {
...
texResident=true;
//Modification////////////////////////////////
skipedGeometryCount=0;
renderTransparency=false;
thePeerRoot.render(); //render opac objects
if(skipedGeometryCount>0)//if there are transparent objects
{
renderTransparency=true;
thePeerRoot.render();
}
//////////////////////////////////////////////
if (thePeerAuxilliaryRoot != null) thePeerAuxilliaryRoot.render();
...
}
...
}
Code: Select all
//JOGLPeerComponent.java
private void preRender() {
...
else if (renderGeometry != null && goBetween.peerGeometry != null ) {
// LoggingSystem.getLogger(this).info("rendering geometry");
//Modification/////////////////////////////////////////////////////////////////
if(thisAp!=null)
{
Object transparencyEnabled = thisAp.getAttribute("transparencyEnabled");
if(transparencyEnabled instanceof Boolean)
{
if(((Boolean)transparencyEnabled).booleanValue() != jr.renderTransparency)
{
jr.skipedGeometryCount++;
return;
}
}
}
///////////////////////////////////////////////////////////////////////////////
Scene.executeReader(goBetween.peerGeometry.originalGeometry, renderGeometry );
}
}
Re: Better transparency with JOGL-Backend
Congratulations on diving in and editing this code!
I've made some small changes to JOGLPeerComponent and checked them in. They should help your code run better. As it stands, your changes to JOGLPeerComponent read the appearance attribute "transparencyEnabled" from the local appearance on each render. This is first of all expensive since it only needs to be done when the appearance changes, not every render. And secondly, it's probably not what you want since the actual valid value of "transparencyEnabled" is the result of an inheritance mechanism involving all the appearances which appear on the path to this scene graph component.
There are already other appearance attributes which have to similarly handled. So I've introduced a new field in JOGLPeerComponent:
This field is then kept up-to-date in the method updateShaders():
updateShaders() is invoked via a listener mechanism whenever any appearance is written which might have an influence on its value. Don't worry, that's already part of the code of the class.
If you want to use this new field, you should update from the svn repository and replace the reads you are now making of the appearance attribute, with reference to this new field. I've tested it out a little to make sure it works, but please post if there are problems.
We may decide to implement the two-pass rendering based on transparencyEnabled as you have done in the official jReality release. But first this would have to be discussed by the group. If we do decide to do so, it will probably be activated by a new field in RenderingHintsShader, something like "twoPassTransparency" so that it only gets invoked when the user really wants it.
I've made some small changes to JOGLPeerComponent and checked them in. They should help your code run better. As it stands, your changes to JOGLPeerComponent read the appearance attribute "transparencyEnabled" from the local appearance on each render. This is first of all expensive since it only needs to be done when the appearance changes, not every render. And secondly, it's probably not what you want since the actual valid value of "transparencyEnabled" is the result of an inheritance mechanism involving all the appearances which appear on the path to this scene graph component.
There are already other appearance attributes which have to similarly handled. So I've introduced a new field in JOGLPeerComponent:
Code: Select all
boolean transparencyEnabled = false;
Code: Select all
transparencyEnabled = eAp.getAttribute(TRANSPARENCY_ENABLED,
TRANSPARENCY_ENABLED_DEFAULT);
If you want to use this new field, you should update from the svn repository and replace the reads you are now making of the appearance attribute, with reference to this new field. I've tested it out a little to make sure it works, but please post if there are problems.
We may decide to implement the two-pass rendering based on transparencyEnabled as you have done in the official jReality release. But first this would have to be discussed by the group. If we do decide to do so, it will probably be activated by a new field in RenderingHintsShader, something like "twoPassTransparency" so that it only gets invoked when the user really wants it.
jReality core developer
Re: Better transparency with JOGL-Backend
Sounds interesting, maybe we should arrange the next jReality-developper-meeting around the beginning of February before Steffen travels away. Should also be interesting for you Marc, then you are able to introduce yourself and your projects at our group.gunn wrote: We may decide to implement the two-pass rendering based on transparencyEnabled as you have done in the official jReality release. But first this would have to be discussed by the group. If we do decide to do so, it will probably be activated by a new field in RenderingHintsShader, something like "twoPassTransparency" so that it only gets invoked when the user really wants it.
I'll write Steffen to arrange that appointment and then I'll mail you the date.
@marc, I'll use your mail, you logged in with ok?
Re: Better transparency with JOGL-Backend
Yes, you can use my mail address. Tomorrow i will meet my project leader and i will discuss this with him. I'm sure he would also like to say something about the project.