Rendering multiple transparent surfaces

Hi,

I’m trying to create a particular scene for which I’m running to issues. Let me describe what I have in mind and show you the issue.

I am trying to render multiple transparent objects that are at approximately similar spatial locations. This is for a biomedical application for brain visualization. I basically need to generate multiple surfaces at similar locations that are ALL transparent.

Now let me show you the problem in a few figures.

Here, you can see an example visualization in which two different groups of meshes (pink and grey) are being rendered as opaque:

As you can see this renders perfectly. Now this is how it looks if only one of the mesh groups were transparent:

Pink transparent:

Grey transparent:

So far it all looks perfect. Pay attention to how the opaque surface underneath is rendered as if it is in a glass container, but yet totally visible.

Now, getting to the issue, this is what happens if both surfaces were rendered as transparent:

As you can see, suddenly the order of visualization gets messy. Some surfaces that are at the back, get rendered first, and surfaces in the front are occluded by them. I imagine this is because panda3d simply checks the boundary box of each surface mesh and decides the order of rendering. (The order of rendering is not decided at the level of individual faces, but at the level of surfaces.

I should mention that in Panda3D, I reorder each surface’s triangular meshes according to their proximity to the camera and that’s how a single transparent surface looks ok. Now I’m wondering how I may solve this issue.

Obviously, one manual laboursome solution would be to first combine all meshes together into a single surface mesh and then reorder all triangles myself. But I am wondering if there is a way to have Panda3D appropriately handle multiple transparent objects correctly (say a glass inside another glass)? To somehow render faces one by one and orderly?

Ah yes–this is a tricky matter!

I think that it’s pretty much as you describe, I believe: objects that are loaded with transparency, or that are placed via code into the “transparent” culling-bin (or another like it), are automatically sorted into order from furthest to nearest. (I think by their origin-points, not their bounding-boxes, however.)

The result is, I daresay, generally good for transparent objects that are separated in space.

However, as you’ve found, if your objects overlap significantly this can be insufficient to produce accurate transparency…

Now, there are a few basic solutions to this–but I doubt that they apply in your situation:

  • One can use a particular transparency mode, along with transparent objects that are either fully opaque or fully transparent, but little in-between.
  • Or one can use additive transparency

But as your surfaces are largely semi-transparent, and presumably not intended to be glowy, neither of those seems likely to be useful to you here…

Could you expand on this a bit more, please? Are you actually altering your meshes on-the-fly, such that the triangles appear potentially in a new order each frame?

Hmm… If you only want to render the forward-facing surfaces, and if the surfaces of the objects don’t intersect, then you could place your objects into a culling-bin of the “fixed” type (such as, well, the bin named “fixed”), giving them sort-values that specify that they render from innermost to outermost.

See this manual page for more:
https://docs.panda3d.org/1.10/python/programming/rendering-process/controlling-render-order

It becomes more complicated if you do want to render rearward faces (as one might when rendering a glass). That I’m not sure of how to do–short of separating the frontward and rearward faces into separate objects on a frame-by-frame basis and giving the resultant sections sort-orders that have them render from back to front…

But then, perhaps someone else will have another idea!

1 Like

Just a thought: You could try to split your mesh into more geoms (e.g. with the script from octreefy optimize collisions - #7 by jbandhauer) and see if the result gets better:
python .\eggoctree.py -v -l -n 1 -r 150 input.egg

If you know that one will always be inside the other, you can be explicit about the ordering to Panda, and get the correct result. But if there is more complex overlap, then this will not be satisfactory.

Otherwise, you need a technique such as depth peeling, which has been requested as a feature here (feel free to add your voice):

Or per-pixel linked lists:

Or Weighted Blended, which gives a technically inaccurate result but perhaps still acceptable:

3 Likes

Yes, so in the past, one of the things that I had to do to make transparency work as expected was to combine all triangles of different surfaces into a single giant surface mesh. Then order all triangles on the fly according to camera direction such that triangles closer to the camera are rendered on top of those that are further away.

However, it is now becoming a bit complicated to merge all surfaces into a single mesh prior to rendering. So I’m really interested in a better solution.

Yes, in my case I think the only thing that would actually work would be some appropriate depth peeling that is implemented at the level of rendering meshes in Panda3D.

I actually have brought this up in an earlier discussion. Back then, I ended up reordering mesh triangles on the fly to dodge the issue. But it’s getting a bigger concern now that I’m trying to render multiple 3D meshes.

I’m actually using Panda3D as a rendering engine for an open-source biomedical imaging application for replicable brain visualizations. I think the implementation of appropriate OIT can really help my case. Are there any plans for adding this feature? I don’t think I’m that familiar with Panda3D code base to be able to offer coding help, but would definitely chip in my 2 cents to vouch for depth-peeling implementation.

2 Likes