Hello hello, to understand my problem, a little background:
I’m working on an ARPG on URP without using DOTS/ECS. I have numerous projectiles on screen simultaneously (between 1000 and 2000). I’ve created a modular system where the projectiles and their logic are decoupled from their rendering and managed by a manager that updates them. So far, everything works well.
The problem arises when I want to render the projectiles. I naively thought of using Particle Systems that are simply made children of the projectiles and create particles based on the distance traveled to create, for example, a fireball. The issue is that as soon as I do this, I can barely manage 200-300 projectiles, and the performance drops drastically.
To give you an idea of what I’ve already done to try to optimize:
- Pooling system for the Particle Systems; they are not destroyed but simply stopped when a projectile is considered ‘dead’ and put back in the pool.
- Making very few and very simple particles; I limit to a maximum of 30 particles per Particle System with a relatively low emission rate between 1 and 6 max, and I only use simple changes (color over lifetime, velocity, and size).
- Using simple shaders.
So I’m starting to run out of ideas to find a solution.
I was almost considering switching to a system without Particle Systems, where I would simply create a simple mesh composition with custom shaders, but that will require more work and I’m not sure it will perform better.
I have also already tested VFX Graph, but it doesn’t really change my problem; it’s even worse in terms of performance (maybe because I’m using it incorrectly).
My issue is having many Particle Systems or Visual Effect components, which seem to overload the CPU.
Do you have any ideas or suggestions to improve this?
Hi, it sounds like you are having problems due to having lots of GameObjects, each with only a few particles.
VFX Graph does support batching/instancing, which is designed to help with this situation. I don’t know a huge amount about it, but, I can point you to the docs: Instancing | Visual Effect Graph | 17.0.3
If that doesn’t help, you can reply again and I’ll nudge someone on the vfx graph team to help out 
If using ParticleSystems, there is an alternative to having 1 game object per projectile. it requires some scripting and is kind of like manual batching. The idea is to have 1 master system, and use the scripted emission (ParticleSyste.Emit) with EmitParams, to spawn particles at the location of each projectile. So you loop around your projectiles and emit particles at the location of each one. There are downsides though. Simulation + Rendering becomes all or nothing, because there is only 1 bounding box for the whole lot. And to do Continuous emission, you would have to emulate your own emission rate for each projectile, to know how many particles to emit on each update frame. This technique is easier to apply when using Burst emission.
Hope this helps!
1 Like
I made a system to manage VFX graphs that is highly performant and gets around the all or nothing issue of the always visible bounding box @richardkettlewell mentioned.
Essentially you collect all the positions (and other custom data) into a GraphicsBuffer and send it to a VFX Graph. Before you add data to the Graphics Buffer, you do frustum culling on it so that the VFX graph will only create particles that could be seen. Then you put a single Visual Effect in your scene with a bounding box that is always seen (either huge extents or attached as a child of your camera).
For me the hard part was figuring out how to modify my single instance VFX graph to handle the GraphicsBuffer, but there is some good info available to help. This was my main source of info: How to Vfx Graph | Qriva
2 Likes