Weird rendering order

Since I can’t answer my own question (today) this will probably sit here forever, but let’s try anyway…

I’ve just started in Java3D and I’m noticing some odd behavior in the following. As you can see, I have a 2D grid of objects that rotates around the x axis. However, as it does so, it sometimes appears that objects that should be behind are overlapping the objects in front of them.

My best guess is that the objects in the back are being rendered after the ones in front of them. If that’s the case, anyway to force the rendering order? Any help would be appreciated.

Some images of what it looks like as it rotates:

that can be sort of Z-index or field-depth, isn’t it ? I’ve never used J3D but this is how I understand back or foreground.

Enabled depth-sorting.

I kind of figured there should be a flag like that somewhere that could be set. This may be a stupid question, but where? I went through every book I have and the API and couldn’t find a place to set depth sorting as either a method or a flag in SimpleUniverse, BranchGroup, Canvas3D, GraphicsConfiguration, or the ViewPort classes.

Google for “Java3D Depth buffer” and check out the first hit.

My first hit came up as this Not sure if that’s where you were pointing me but I’m not seeing anything helpful.

While I know you are trying to help and can appreciate the “teach a man to fish” thing, I know this can’t be more than a few lines of code setting some int or boolean somewhere. Sometimes just seeing the two lines of code sparks more than the hours of googling, thumbing through books, reading the java3d tutorial pdfs, and searching the forum archives.

I was originally told to enable depth-sorting but it wouid seem what I should really be looking at is the depth buffer instead. If so, I thought that it was already defaulted to LESS_OR_EQUAL. If it just needs to be turned on, then that’s where I’m not sure how it should be done. With the Appearance object I can use RenderingAttributes so I guess I was expecting something similiar for a BranchGroup.

Hm… is google personalizing the hit-results or what…

I got this link:
http://java.sun.com/products/java-media/3D/forDevelopers/J3D_1_3_API/j3dapi/javax/media/j3d/RenderingAttributes.html

That is odd. I tried googling with two different computers and got a different result than that both times (they were both the same).

Appearance app = new Appearance();
RenderingAttributes ra = new RenderingAttributes();
ra.setDepthBufferEnable(true);
app.setRenderingAttributes(ra);

Since both Appearance and RenderingAttributes are NodeComponent subclasses I would think that I could just use the following:

RenderingAttributes ra = new RenderingAttributes();
ra.setDepthBufferEnable(true);

Although this is the point where I get lost. Where do I set the ra in the scenegraph? BranchGroup is a subclass of Node and I haven’t found any methods that allow me to set RenderingAttributes like I can in Appearance. I tried using this with each object that I added to the scene, but that didn’t work either.

Are you sure the model is not transparent in some way. Depth write is disabled by default on transparent objects. You could try the following:
View.setTransparencySortingPolicy(View.TRANSPARENCY_SORT_GEOMETRY)

This will sort the objects back to front.

That appears to have been it, thanks. I had the following method call in my constructor. So does that mean there isn’t any way to currently use any type of transparency and still maintain the front to back rendering? In this instance all of the objects were set to opaque anyway.

setVisibility(IBoardConstants.VISIBLE);

public void setVisibility(int visibility)
  {
    // let transparency value change at run time
    transAtt = new TransparencyAttributes();
    transAtt.setTransparencyMode(TransparencyAttributes.BLENDED);
    transAtt.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);

    if (visibility == IBoardConstants.VISIBLE)
    {
      visualState = visibility;
      transAtt.setTransparency(0.0f);     // opaque
    }
    if (visibility == IBoardConstants.INVISIBLE)
    {
    	visualState = visibility;
    	transAtt.setTransparency(1.0f);
    }
    cellApp.setTransparencyAttributes(transAtt);
  }  // end of setVisibility()

You can use View.setDepthBufferFreezeTransparent(false) to enable depth write on transparent object. Then the depth buffer attributes will work in the same way as on opaque objects. Transparency is a pain in the neck because of the depth buffer issues. Use it only when you must.

If you just want to hide your object there is two other ways to do it. One is to use a switch to switch between a an empty BranchGroup and the visible object. The other is to use RenderingAttributes.setVisible(boolean) on the objects Appearance.

All very useful things to know. Thank you for your help Tom, I really appreciate it.

Alright guys, I am having the same problem with transparent objects.
Here is the situation.

All objects that are transparent are drawn properly before a HUD is added.
However, when I add a HUD and start removing and adding Objects to the scene graph, then I get issues listed above.

Here is the structure of my HUD. The HUD branchgroup contains quad arrays that have an image applied to them as a texture.


TransformGroup (Camera Location)
   -> Platform
   -> BranchGroup (HUD)

Here are some images that illistrate my problem.

Before branchgroup action

After branchgroup action

Have you tried using an OrderedGroup to render the hud after the platform. Might help.

Do you mean to have a structure like this?


TransformGroup (Camera Location)
    -> Platform
    -> OrderedGroup (HUD)

Sorry, I did not see that you meant ViewPlatform, meaning this is on the view branch. Then you OrderedGroup wont work.

Unfortunately it is impossible to do a decent hud in Java3D. What you want is to first draw the level, then draw the hud. In Java3D there is always a catch. Here is the alternatives:

  1. use Canvas3D.postRender()
    Performance is rubbish

  2. Put the hud in the view side, under viewTG (cameraTG).
    The hud will not move relative to the viewTG. But there is no way to force the rendereing order so one has to rely on the depth buffer. You can try to move it as close to the view as possible, but there will problem with the level geometry moving infront of the hud.

  3. Use an OrderedGroup on the level side of the scene graph.
    The hud has to be placed under a TransformGroup wich synced with the viewTG. The problem is how to sync the to viewTGs. WakeupOnTransformChange behior on the viewTG can not be used to update the viewTG on the level side because the transform wont be set until the next frame. So the hud will lag after the view. See the same problem with Billboards. Can be the best solution if you only set the viewTG form one place, and can update both at the same time, in a behavior.

  4. Never use the TransformGroup attached to ViewPlatorm.
    Instead have a TransformGroup at the root of the level geometry to move the camera. Then an OrderedGroup under to force level rendering before hud. This would probably work, but performance should suffer because all the level is constantly moved with the view.

Your using 2). In wich case you should enable depth write with View.setDepthBufferFreezeTransparent(false), move the hud as close to the fornt clipping plane as possible and hope for the best.

Btw, the screenshots are to small to see what is going on

Alright. Here are some more (larger) screenshots

The first 2 screens are how it looks when transparency is being rendered corectly

Here the cockpit (which is transparent) is being rendered on-top of the body of the craft

I’ve also tried to set the depth buffer as well as the sorting policy and am still getting the problem.

Alright, looks like I found the problem but i"m not sure why its a problem … maybe some-one can shed some light on this.

So in order to take a screenshot, I created a second Canvas3D object and added this to the view. Then when the user asks for a screenshot, the second canvas is used for rendering the screen and then an image is taken from it and eventually saved out.

When I don’t include the 2nd canvas to the view, the problem goes away (this is with the depth buffer and sorting policy set). Any ideas why this is the case?

http://www.sgclub.com/imagehosting/2572473ab2d9c58be.png

hi i am having a problem with depth buffer for objects that are supposed to be intersecting. can anyhow help figure out what is the problem?

i already turned on the depthbuffer and it works fine. just the problem with intersecting objects like shown in the picture above.

help me please it’s giving me a headache :’(

i think i figured out the problem. It’s because i gave all my geometries a transparencyattributes.

is there any way at all to depth buffer intersecting transparent objects properly? per-geometry doesn’t work because my objects are intersecting… :frowning:

I just thought of something to solve my own problem!!!

i just switch off transparency whenever the value of transparency is 0~

i hope it works~ :slight_smile:

edit: ya it works now~ ;D