Search Unity

performance advice for custom ecs based particle system.

Discussion in 'Entity Component System' started by tommox86, Jun 13, 2021.

  1. tommox86

    tommox86

    Joined:
    Apr 30, 2015
    Posts:
    88
    I have opted to create my own particle system using the unity jobs system due to the hybrid entity system causing garbage per frame when using the included system with hybrid system.
    My particle system works very well however there seems to be a noticeable performance hit when processing many particles.
    to quickly summarize how the system works for a rocket projectile, the projectile will generate around 1500 smoke particles which are just quads with the default-particle system attached to it and the parallel jobs system moving each particle to simulate smoke. visually its pretty much identical to the unity particle system, though it generates many less particles and seems to utilize more cpu usage.
    the meshes over time scale down, and move from left to right. I have enabled dynamic batching, only a very small amount of batches are saved. the shader is alpha blended pre multiplier with the default particle as the texture.
    i am also grouping multiple jobs into one systembase. example:
    generate_particles()
    move_projectile()
    apply_randomize_movement()
    i know im missing some performance tweaks (googled many hours) any pointers would be appreciated
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Could try generating or altering a single mesh of quads. A lot of separate draws of quads is terribly bad in any engine including with DOTS unless you're using instanced indirect to draw them in one go.

    Sorry if I'm off base.
     
    tommox86 likes this.
  3. tommox86

    tommox86

    Joined:
    Apr 30, 2015
    Posts:
    88
    any tips appreciated. instanced indirect, could you elaborate?
     
  4. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    https://docs.unity3d.com/2021.1/Doc...rence/Graphics.DrawMeshInstancedIndirect.html however I have no experience in DOTS rendering. It should just work with the right kind of data fed to it though. You'd need a compute shader to help with that. If you prefer to use CPU then perhaps https://docs.unity3d.com/2021.1/Documentation/ScriptReference/Graphics.DrawMeshInstanced.html would work.

    Again, I am not fully familiar with the situation with DOTS but regardless one would probably want to control the GPU directly here and submit a whole bunch of draws in one go, and that's what these do.

    I would also investigate DOTS mesh API because from casually skimming forums I recall this is quite good for procedural meshing which is what particles are really.
     
  5. mikaelK

    mikaelK

    Joined:
    Oct 2, 2013
    Posts:
    284
    Whatever you do, don't use the sharedcomponent. :D
     
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    Don't use instancing for quads. It is about an order of magnitude slower on the GPU compared to a dynamic mesh with so few vertices per instance.

    However, since you seem to be suffering CPU issues, that suggests you are not using parallel jobs or Burst or are doing something really expensive on the CPU. Can you share the code that is slowing everything down when looking at the Profiler timeline view?
     
  7. tommox86

    tommox86

    Joined:
    Apr 30, 2015
    Posts:
    88
    i am using both burst and parallels jobs. issue is only apparent when firing around 20 missiles or more. system is amd ryzen 9 3900x , gpu gtx 1650. sure when i get back back to desk ill screenshot. . having a look at the unity particle system it seems to be functioning the same way. i.e generating a billboarded quad and interpolating particles using the settings in the particle system...
    is there a way to dynamically batch the particle quads?
     
  8. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    "Dynamic batching" is just a fancy term for packing all the quad into a single mesh and then drawing that mesh. Unity may do that for you when using MeshRenderers and such. But it won't when you use the Graphics API (that I am aware of), so you are better off doing it yourself using the Burst-friendly Mesh API.
     
  9. tommox86

    tommox86

    Joined:
    Apr 30, 2015
    Posts:
    88
  10. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    4,262
    tommox86 likes this.