[SOLVED] High performance workarounds for many transparent meshes

I’ve been working on a mobile game where overlapping transparent meshes are very necessary, and they often spawn in groups, like shown here:

The problem with this, is that having up to 10 overlapping meshes that all use alpha transparency in their shared material can be quite performance demanding and often causes down to 25 - 45 fps in mobile devices.

However, I’ve noticed that I can achieve the same visual effect with particle systems. Here I have 100 particles all rendering with depth testing and alpha transparency with no noticeable performance issues

I think I know the general concept behind particles, from what I understand, they are each a quad, all part of the same procedural mesh that gets it’s vertices updated each frame based on velocity and other properties. That mesh is then passed to the gpu and all of the triangles are rendered.

However, I can’t quite work out why it’s so much more performant. Yes, I get that in this case it’s only one draw call vs 10, but it still seems that should be negligible. There must be some sort of way that the shader for the particle system is optimized, maybe the particle shader takes advantage of the single mesh somehow?

Either way, for some workarounds I am attempting to come up for this issue, I have come up with some potential solutions.

Option 1:
I was thinking that each time one of the transparent is to be created (happens programmatically throughout the game), I instead emit a particle from the particle system and reposition the particle to fit the orientation of the glass pane.

The issue with this, is that when I was messing with particle systems before, I couldn’t find a way to position an individual particle in the world, and looking through the engine source didn’t seem to provide me with any insight. I also notice that each particle seems to need to be oriented in the same direction, and in this case the glass panes orient themselves along the curving tube that the player travels through, but there may be some workaround to that as well.

Option 2:
I could procedurally generate my own mesh and append a quad to it at the desired orientation of the glass pane each time a new one is created. This would essentially work the same way as a particle system as far as I know, and potentially allow for the same amount of efficiency.

The issue with this, however (aside from being a pretty significant amount of work to implement), is that I fear the same performance issues will arise if I try to use a material with alpha transparency, or that the overlapping alpha transparency would not be visible, since it is all part of the same mesh. This would probably work if I could use the same shader that the particle system uses for rendering it’s mesh, but I have no idea how I would go about doing that.

Before I spend a bunch of time implementing either of these. Do any of these solutions seem reasonable at all? Is there another more obvious solution that I’m missing? How do I use the material used for the particle system on a custom mesh, or is that even possible?

It’s possible the material you use for the meshes is expensive. Does it use many textures? Casts / receives shadows? Normal maps?

You could try and create BasicMaterial which is very cheap, and assign it to the mesh instances using the script.



Does it use many textures? Casts / receives shadows? Normal maps?

No textures, just a solid emissive color and alpha opacity, as seen in the screenshot.

Thanks for the idea about BasicMaterials though, I was unaware of that, I’ll have to try it out when I get a chance! Do you happen to know if the basic material supports alpha blending?

See the documentation I sent … there’s a blendType on it.

Your set up seems fine with just emissive color and opacity. Perhaps install Spector JS, capture a frame … and inspect the fragment shader for those render calls … they should be pretty simple (post here if you want).

Wow, this is brilliant, the performance gain from changing the material to basic material is incredibly significant!! Thanks a bunch!