- Home /
Is there a way to get the number of particles from a single particle system being rendered on a particular camera?
Does anyone know of a way to get the number of particles from a single particle system that are currently being rendered on camera? So the number should exclude particles that are being emitted but not currently being rendered.
This would be useful for something like emitting a swarm of bees from a particle system and having the volume of the sound the bees make relative to how many are on screen. This might ordinarily be done by increasing the volume as you increase the proximity to the particle system, but here I'm looking for a more direct link between the particles you can see and the audio volume.
Thanks very much!
Answer by richardkettlewell · May 30, 2019 at 09:43 AM
(Or, if it's just one camera per frame, you could do all the testing and maths in script via GetParticles or the C# job system API, but it might be quite expensive)
Thanks for the extensive answers! Can you give me an idea of how this would be done with GetParticles and the C# job system? I had a look at GetParticles, but couldn't see how I'd use it since there's no OnBecameVisible() for non $$anonymous$$onoBehaviours.
First, you would have to get hold of the camera you want to test against in your script. Then test if particlesystemrenderer.bounds is inside the camera frustum. If it is, call GetParticles. Then, for each particle, build a bounding sphere using particle.position and the max dimension of particle.size.xyz (if using 3d size). Then test that sphere against the camera frustum too.
You can probably google for how to test if boxes and spheres are visible to unity cameras, if you don't already know how, e.g. https://answers.unity.com/questions/8003/how-can-i-know-if-a-gameobject-is-seen-by-a-partic.html links to GeometryUtility.CalculateFrustumPlanes and GeometryUtility.TestPlanesAABB docs pages.
Answer by richardkettlewell · May 30, 2019 at 09:41 AM
There is nothing built-in for this - we don't do any kind of per-particle visibility checking.
To do it, if you really want to, you would need to:
Write a custom shader to detect and count the number of onscreen vertices (InterlockedAdd, if the vertices are within the view, eg projected coords are in the -1 to +1 range)
Store the count in a ComputeBuffer (StructuredBuffer)
Use the async readback API to efficiently get the number of rendered verts back to the CPU
Divide the result by 4, because each billboard particle is made up of 4 vertices
Set the volume of the audio based on the result
It's pretty complicated! :)