Search Unity

  1. Unity Asset Manager is now available in public beta. Try it out now and join the conversation here in the forums.
    Dismiss Notice

Official Particle System C# Job System support

Discussion in 'Particle System Previews' started by richardkettlewell, May 1, 2018.

Thread Status:
Not open for further replies.
  1. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    Particle System Job System support has moved out of Experimental status in 2019.3.0a9. You can use that minimum version of Unity to make use of this feature, or download an Experimental build from the link below.

    The API has changed significantly, in order to support the following key features:

    * JobHandle support, allowing you to chain jobs together
    * 3 types of job
    - a single job with access to all particles (IJobParticleSystem / Schedule)
    - a for-each job with access to the particle at the given index (IJobParticleSystemParallelFor / Schedule)
    - a batched version of the for-each job, similar to IJobParallelFor vs. IJobParallelForBatch (IJobParticleSystemParallelForBatch / ScheduleBatch)

    The biggest change is in how you schedule Particle System jobs. It is now vital that it is done in a new MonoBehaviour callback: OnParticleUpdateJobScheduled. This callback occurs after the native built-in particle jobs are scheduled, and scheduling your jobs here ensures that the managed job runs after the built-in update, and can return a JobHandle that reflects this job-chain. You are able to chain multiple jobs from within this callback.

    (eg a job to build a spatial structure of the particles such as a KD-Tree, followed by a job to perform some spatially aware logic such as inter-particle collisions.)

    Here is a new example of a (not very exciting) script that works with the latest demo:

    Code (CSharp):
    1. using Unity.Collections;
    2. using UnityEngine;
    3. using UnityEngine.ParticleSystemJobs;
    4.  
    5. public class ParticleJob : MonoBehaviour
    6. {
    7.     private ParticleSystem ps;
    8.     private UpdateParticlesJob job = new UpdateParticlesJob();
    9.  
    10.     void Start ()
    11.     {
    12.         ps = GetComponent<ParticleSystem>();
    13.  
    14.         job.color = Color.red;
    15.         job.size = 0.35f;
    16.     }
    17.  
    18.     void OnParticleUpdateJobScheduled()
    19.     {
    20.         /*var handle =*/ job.Schedule(ps);
    21.     }
    22.  
    23.     //[BurstCompile] // Enable if using the Burst package
    24.     struct UpdateParticlesJob : IJobParticleSystem
    25.     {
    26.         public Color color;
    27.         public float size;
    28.  
    29.         public void Execute(ParticleSystemJobData particles)
    30.         {
    31.             var startColors = particles.startColors;
    32.             var sizes = particles.sizes.x;
    33.  
    34.             for (int i = 0; i < particles.count; i++)
    35.             {
    36.                 startColors[i] = color;
    37.                 sizes[i] = size;
    38.             }
    39.         }
    40.     }
    41. }
    Performance

    Here is some simple profiling to measure the difference this feature can make.
    We created 128 systems, each with 1000 particles (128K particles total). Each system uses a managed job to make its particles chase the cursor.

    With Set/GetParticles on the main thread:
    Total frame time: 23ms
    Particle script code time: 14.7ms

    With Managed Burst Jobs:
    Total frame time: 8ms
    Particle script code time: 0.3ms (main thread) + 0.03ms (jobs across 11 worker threads)

    Hopefully this gives an idea of the boost this feature can give - applying a simple behaviour to 128K particles in 0.3ms can unlock a lot of interesting use cases.

    Download the Editor here: https://beta.unity3d.com/download/558b031e02d4/public_download.html
    Leave us your feedback here: https://forum.unity.com/threads/feedback-particle-system-c-job-system-support.529286/

    =====================================================================

    The old experimental version of the feature is described below and has been preserved here for posterity:

    We have begun investigating how the C# Job System might interact with the Particle System.

    The idea is to allow particles to be manipulated in jobs, with no copying of data (i.e. direct access to the particle data on the native side).

    Here is an example of a (not very exciting) script that works with the demo:

    Code (CSharp):
    1. using Unity.Collections;
    2. using UnityEngine;
    3. using UnityEngine.Experimental.ParticleSystemJobs;
    4.  
    5. public class ParticleJob : MonoBehaviour
    6. {
    7.     void Start ()
    8.     {
    9.         var job = new UpdateParticlesJob();
    10.         job.color = Color.red;
    11.         job.size = 0.35f;
    12.         GetComponent<ParticleSystem>().SetJob(job);
    13.     }
    14.  
    15.     struct UpdateParticlesJob : IParticleSystemJob
    16.     {
    17.         [ReadOnly]
    18.         public Color color;
    19.  
    20.         [ReadOnly]
    21.         public float size;
    22.  
    23.         public void ProcessParticleSystem(JobData particles)
    24.         {
    25.             var startColors = particles.startColors;
    26.             var sizes = particles.sizes.x;
    27.  
    28.             for (int i = 0; i < particles.count; i++)
    29.             {
    30.                 startColors[i] = color;
    31.                 sizes[i] = size;
    32.             }
    33.         }
    34.     }
    35. }
     
    Last edited: Jul 22, 2019
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    I've written a small example package to demonstrate 2 use-cases:

    * Drawing lines between nearby particles
    * Self-collision within a Particle System


    The self-collision demo isn't entirely stable - you are welcome to improve it and share it on the feedback thread!

    They require the Collections and Burst packages to be installer via the Package Manager.

    UPDATE: Big thanks to @Creaturtle who has suggested some bugfixes to the self-collision demo, which increases its overall stability and robustness! I've replaced the old package with a new one that contains these fixes!

    UPDATE: Thanks to @Josp101 for pointing out that Unity 2020 replaces Concurrent with ParallelWriter in the NativeList code, which causes a bit of upgrade pain for this demo. I've uploaded JobsExample_v2 for anyone using Unity 2020.
     

    Attached Files:

    Last edited: Jul 13, 2020
Thread Status:
Not open for further replies.