VFX graph instancing not working

I am using VFX graph for explosion in ECS game. At the start I instantiate 100 entities of Visual effect gameObject using GameObject authoring, and then just enable the explosion entity on hit. I have instancing enabled but it seems the explosions are taking 100 draw calls in frame debbugger. I have attached the relavant screenshots. How can I reduce the draw calls?




Hi!

Having many drawcalls in frame debugger does not necessarily mean that instancing is not working. In some cases we decided to render instances separately for performance reasons.

In your case, because indirect drawing is active (default for transparent particles), each particle system will be rendering only the active particles, which will be different for each visual effect instance. Then there are 2 options:

  • We could render all in one drawcall, and internally in the shader determine which particle belongs to which system. This could be implemented using a prefix sum and binary search, for instance, but it has a cost per vertex.
  • We can render each instance individually, but all together, preparing the shader only once. This is what we ended up doing.

The cost of the actual drawcall is not that much, it is usually everything else (setting uniforms, activating the shader, etc).

Also, even if there are many drawcalls, the compute shaders should be properly batched.

One way to ensure if instancing is working properly would be to do some profiling, looking for the ApplyShader marker. It should be done one per batch*, instead of one per drawcall.

*in some cases the batch can be split, for example if other drawcalls must be rendered between instances due to sorting. This would require one ApplyShader for each split.

Did you notice a big performance hit? If so, what seems to be the marker that is taking the most time?

@gabriel-delacruz Thanks for the information, it seems I had another vfx grah effect for laser and when I switched to line renderer instead of vfx graph the draw calls decrease by coming down under 100. There was no hit in performance when I was using vfx graph. Though now performance seems to be much better.

I am not sure how to see this ApplyShader marker in profiler, if you can guide me please.
Also another question, does it mean that I can’t use lot of instances of vfx graph in a ECS project for mobile? As it shoots up the draw call super fast.

So, I used a single vfx graph with graphics buffer for all the explosion and that decreased the draw call.

Hi!

Regarding your question, I think in general you should be looking at times and framerate, not only drawcalls, when profiling. In this particular case, the cost of each drawcall is less than it would be in other cases.

To look for the ApplyShader marker, you can use the profiler, capture some frames, and just type the marker name in the search field.

You can see how many times is being invoked in the Hierarchy view.

In the scenario that you are describing for mobile, I think it is worth trying and comparing performance. Otherwise, the solution is combining them as you already did.

Glad to see that you have it working now!

Hi, there is a simple solution to your problem. You have two systems in a single vfx graph asset, when you instantiate an entity/gameobject with such an asset unity automatically creates two batches for such a system.

You can try to turn off one of the systems, increase batch capacity to ~1000, turn on instancing and see if it works; in my case it helped me to reduce my 2000 batches to 1 batch for ~1000 entities. If you want both spawn systems to work simlutaneously, you have to create two separate vfx graphs and gameobjects and instantiate them with the same transform properties, this way you can drastically reduce number of batches, but you’ll have x2 number of transforms to calculate, which isn’t a big issue if you’re using ECS system.