Different transparency for mesh instances

Good time of day, everyone,

There doesn’t seem to be a way to do this, but I will ask anyway. :slight_smile:

I have a few instances of the same mesh.
The documentation here says “You also have the opportunity to specify per instance values for any attribute”.

I can set different colors for each instance using instancedBuffers (via VertexBuffer.ColorKind kind): https://playground.babylonjs.com/#8L50Q3#1

Is there a way to set transparency (alpha) for each instance separately? The use case would be - I want to only keep a few instanced meshes opaque and set alpha for the rest to, say, 0.5.

Thank you,
Anton.

Heya, for example here each instance has a different random alpha value (line 17), but also hasVertexAlpha must be set to true. (line 8). :slight_smile:

4 Likes

Well that was easy :slightly_smiling_face:
Thank you!

Actually sorry, I was too quick to declare a victory…
It looks like when hasVertexAlpha is set to true (line 8) even a maximum alpha of 1.0 (line 17) still causes some back-to-front rendering order issues: https://playground.babylonjs.com/#8L50Q3#96
Just rotate the scene and you will see what I mean - the boxes that should be in front are sometimes overlapped by the boxes that should be in the back.

Has this only been fixed in 5.0.0 by this major update:

“Added support for Order Independent Transparency on simple scenes. scene.useOrderIndependentTransparency = true now makes transparent meshes shade correctly when stacked onto each other. (CraigFeldspar)”

If I set this to true on the scene (line 3) the rendering order seems to get fixed, but the scene seems to become more aliased (and slower performing): https://playground.babylonjs.com/#8L50Q3#97

@CraigFeldspar can comment on this, but OIT is far from being free, this is actually pretty expensive.

2 Likes

It is indeed, you actually render each transparent mesh roughly 5 times more. In a situation where you have lots of different meshes/materials it can get your CPU really strugling

Thanks. So am I right to think that the only way to fix the back-to-front render order issues in this playground (instances with hasVertexAlpha = true and alpha = 1.0) is to set scene.useOrderIndependentTransparency = true? https://playground.babylonjs.com/#8L50Q3#96

Or there is another approach that will work / be less costly?

You could have two meshes, one to build the opaque instances from and the other one to build the transparent instances.

Note that since 5.0 you now have the Mesh.INSTANCEDMESH_SORT_TRANSPARENT flag to instruct the engine to sort the transparent instances from back to front.

I tried to do it in this playground (line 2), but now getting a “disco ball” effect in the scene :slight_smile: : https://playground.babylonjs.com/#8L50Q3#100

Something else is wrong?

You can’t use setVerticesBuffer to set the color buffer because doing it that way bypasses the operations that the renderer is doing to get the right instance data (here color) for each instance. You must use registerInstancedBuffer instead:

Note that you will see some artefacts when rotating the camera because the sorting is done using the center of each mesh.

3 Likes

Ok thank you, I think this gives me what I need now - scene with instances of the same mesh, some transparent and some opaque and no rendering order issues: https://playground.babylonjs.com/#8L50Q3#102
I think the fact that sorting is done using mesh centers is not going to be an issue.

The bottom line is - we are on Babylon 4.2.0 now, so to do the above we have to migrate up to 5.0.0 at least.