2
\$\begingroup\$

I'm using jME3 (JMonkeyEngine). I’m setting a geometry (a box with a bullet hole material/texture) to show transparency using

material.getAdditionalRenderState().setBlendMode(BlendMode.Alpha);
geometry.setQueueBucket(Bucket.Transparent);
geometry.setMaterial(material);

I guess it works, but this happens: enter image description here

Basically, instead of the transparent part of the image (bullet hole) showing iron man’s (first model) red armor, it shows the ninja’s green clothing, which is in the same position but behind the iron man model. This happens even when the geometry is in front (between the camera and the both models) of the models, so idk what’s happening. Any help is appreciated!

\$\endgroup\$
2
\$\begingroup\$

Queue buckets are not deprecated and are absolutely intended to solve this very problem.

Objects are rendered in the scene in bucket order, i.e. Opaque is rendered then later on Transparent - there are other buckets too.

Within the bucket they are sorted based on a geometry comparator. For the opaque bucket this draws near to far, for the transparent bucket it draws far to near.

This is to reduce overdraw on opaque objects (so after you draw a large object in the foreground you don't also both drawing the pixels for all the small objects behind it). For transparent objects though you must draw the furthest away ones first so they appear behind the ones nearby and to allow transparent objects to be drawn as well as possible. Unfortunately it's impossible to sort objects correctly in all cases (for example overlapping objects) but the engine will try.

You also have alpha discard etc available for transparent objects to prevent them writing to the depth buffer in transparent areas to help improve this.

So putting the object in the transparent bucket means that all the opaque objects are drawn first. Only afterwards is your bullet hole drawn, so this then gives the result you are looking for.

Before the objects were all in the opaque bucket so they were being sorted near->far. The bullet hole was being drawn first and writing to the depth buffer. The man was then being drawn, but because the depth buffer thought the bullet hole had already drawn over that area nothing was drawn there.

I'm not sure why the green man was still being drawn as I'd expect him to be drawn last, maybe the extents of the model just pushed in front of the bullet hole or something though.

\$\endgroup\$
1
\$\begingroup\$

This problem is caused by sorting order and depth buffer. You get this result when the green model is rendered first, then the translucent polygon and finally the rest of the model. The translucent polygon is blended with whatever is behind it at that moment. It also writes the whole polygon to the depth buffer and nothing behind it is rendered anymore after that.

To solve the problem in this case you can first render all opaque models and then all translucent models. This gives correct results if there are no overlapping translucent polygons. If there are, the problem gets a lot harder. See Rendering order and What is the order-less rendering technique that allows partial transparency?

\$\endgroup\$
  • \$\begingroup\$ I understand what you mean but is there a jme-specific way to do this? I've tried adding the translucent spatial to the root node first, but it doesn't seem to do anything. \$\endgroup\$ – Jimmt Dec 13 '13 at 6:34
  • \$\begingroup\$ I haven't used JMonkeyEngine, but some googling reveals that you should specify QUEUE_TRANSPARENT for Spatial.setRenderQueueMode() for the box. \$\endgroup\$ – msell Dec 13 '13 at 7:42
  • \$\begingroup\$ I tried that too, but I think it's deprecated... \$\endgroup\$ – Jimmt Dec 15 '13 at 19:04
  • \$\begingroup\$ I didn't find anything suggesting it's deprecated. Do you have a reference for that? Anyway, did it solve the problem? \$\endgroup\$ – msell Dec 16 '13 at 8:33
  • \$\begingroup\$ Well, I don't have the method, and my libraries are updated. I think they might have changed it to setQueueBucket() but I already have that. \$\endgroup\$ – Jimmt Dec 17 '13 at 2:10
0
\$\begingroup\$

Using

geometry.setQueueBucket(Bucket.Translucent);

seems to have solved it, though I don't really know why. Maybe SceneProcessor is messing with my render order?

\$\endgroup\$
  • \$\begingroup\$ See my answer, I've explained why. \$\endgroup\$ – Tim B Jan 4 '14 at 21:06
  • \$\begingroup\$ sorry for late response, but thanks for the explanation. Accepted yours as answer \$\endgroup\$ – Jimmt Jan 16 '14 at 6:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.