Search Unity

Feedback Particle System C# Job System support

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

  1. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    I'd love to hear your numbers for the particle jobs if you are happy to share them! Remember to use [BurstCompile] on your jobs! ;)
     
    TeotiGraphix likes this.
  2. mnarimani

    mnarimani

    Joined:
    Mar 27, 2017
    Posts:
    214
    Is this feature automatically activated for Unity 2019.3.0a9+?
    Also, do you have any plans on developing particle systems for ECS?
     
    Opeth001 likes this.
  3. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    Yes :)

    No plans; it probably won’t happen for the current Particle System.
     
  4. KokkuHub

    KokkuHub

    Joined:
    Feb 15, 2018
    Posts:
    142
    What is even the point of running the particles on another thread if the main thread sits idle waiting for it to finish?
    upload_2020-1-6_21-15-55.png
     
  5. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    If you have more than one particle system to update, they should run in parallel (unless it's a sub-emitter) Indeed for the singular case it's sub-optimal.
     
  6. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    88
    Hello!
    Where and when Particle System Jobs would be available in public build?
     
  7. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    It’s shipping in 2019.3 :) can use the final version in any recent beta version.

    An experimental version exists in 2019.1 and 2019.2 but we made breaking changes for 2019.3, so best to start there if possible. Who knows, maybe it’ll make it out of beta soon... ;-)
     
    konsic likes this.
  8. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    88
    Found your similar answer in some PS-Jobs thread (^ thank you for clarifications! Unfortunatly, I'd can not use PS-Jobs in production, 'cause 2019.3 would realy non-production ready and migration would be painful, but we're shipping in march 2020 :( Would experiment with it. Planning to replicate Legacy Lens Flare System with it
     
  9. Opeth001

    Opeth001

    Joined:
    Jan 28, 2017
    Posts:
    573
    Hello Everyone :)

    sorry if my Question looks stupid :p, but what's the benefits of using the IJobParticleSystem knowing that sadly there is no way to complement it with ECS ?
    1) is it only for Complexe Particale systems and used to free the main thread by running everything in worker threads ?
    2) is it worth using it even for simple particle systems ?

    Thanks in advance!
     
  10. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    88
    I've few more questions:
    - IJobParticleSystemParallelFor is not IJobParallelFor ? This mean, that I can't combinate it with other IJobParallelFor?
    - Somewhere you've write that PS-Jobs should be Scheduled int MonoBehaviour callback
    OnParticleUpdateJobScheduled. But where it can be created,in MonoBehaviour.Update? FixedUpdate, [UpdateBefore(typeof(Update)]ComponentSystem.OnUpdate?
     
  11. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    Hey! Not a stupid question ;)

    C# Jobs and Burst work very well with the MonoBehaviour workflow. If you ever wrote ParticleSystem.SetParticles or ParticleSystem.GetParticles in your MonoBehaviour scripts, you could use this new feature to do it much more efficiently.

    1) Freeing up the main thread is indeed a great reason to use this. Even doing something on 100 particles on the main thread probably has a non-negligible cost. I would always suggest measuring. Perhaps the cost of setting up and scheduling a job, to do something simple on 5 particles, might not be worth it, especially if the job needs lots of inputs. There will be a tipping point.

    2) Same as 1) really ;-)
     
    mitaywalle and Opeth001 like this.
  12. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    Correct, it has its own job type because the particle data is passed in, and the for-loop count is predetermined based on the particle count. But it uses the same JobFences as the rest of the job system, so it can be used in dependency-chains with the regular job types.

    Yes, it must be scheduled in OnParticleUpdateJobScheduled. This is to ensure that it does not collide with the built-in update that Unity runs, based on the modules you have enabled in the Inspector.

    If you have other jobs that you want to run as dependencies, you can do it, because the script functions run is a well-defined order:

    FixedUpdate: Schedule a job
    Update: Schedule a job that depends on the first job
    OnParticleUpdateJobScheduled: Schedule the particle job, make it depend on the Update job (i.e. if it has an input that is calculated by the Update job)
    LateUpdate: Scheduling a particle job also returns a JobFence. So you can schedule more jobs here that run using the output of the particle job. Or you can simply schedule more jobs directly in OnParticleUpdateJobScheduled.

    wrt ComponentSystem.OnUpdate.. I'm not very familiar with using ECS and MonoBehaviours together, but I suspect that it's not easy/possible.
     
    mitaywalle likes this.
  13. sstrong

    sstrong

    Joined:
    Oct 16, 2013
    Posts:
    1,364
    Although we've not got particles working in Jobs yet, in one of our assets, Sci-Fi Ship Controller, we have ECS working with MonoBehaviours. Our main ship physics etc code runs as a monobehaviour and there is an option to run projectiles through our weapons system as Entities (updated in parallel with Jobs). If ECS / DOTS is enabled, we also do ray casting in a job.

    Recently we've got some interaction working with the new DOTS-based Unity Physics too. So, it is definitely possible - although not that obvious how it should work together.

    As tools developers, we took this approach because we figured for the foreseeable future people would want to combine monobehaviours (which everyone knows) and DOTS / ECS.

    Certainly having the option of running some of our particle systems with DOTS is appealing - although we understand they are very different from what we currently think of in terms of particles.
     
    richardkettlewell likes this.
  14. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    88
    Thanks for clarifications! Would continue to experiment
     
    richardkettlewell likes this.
  15. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    I am really glad that we have this feature in Unity. It allows us to do far more particles :)

    I was wondering, is there a way to turn off the simulation altogether and manipulate the aliveTimePercent, position, velocity, etc. ourselves?
    We would want the aliveTimePercent to be used for curves like ColorOverLifetime and ShapeOverLifeTime, but the lifetime of our particles cannot be determined a priori.
    I.e. we may want to start at 0, loop back to 25 when we hit 75, and jump to 75.001 when an event happens and kill the particle at 100.
    Or in some cases, when the event occurs lerp from the current percent to 100 in a fixed period of time. (i.e. for a fade-out)
    It is also important that we can set the position and velocity and not have the position automatically updated by the velocity.

    Thanks!

    Tangent:
    Now if only we could get mesh instancing to work with our SRP so that we could get away from sprites and still have the render thread keep up with the particles that the CPU can simulate)

    Tangent 2:
    Somewhere it was mentioned that using percent had better precision than 0..1.
    How is that possible? Isn't it the other way around? 100 is not a power of two, you cannot divide without losing precision.
     
    Last edited: Feb 25, 2020
  16. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    You could try setting the simulation speed option to 0. That ought to effectively disable all the built-in simulation.

    Let me know if it works - I could perhaps add an optimisation to skip all the built-in logic when this value is 0, to eliminate any wasted computation, if it might help you further.

    Glad you’re finding the feature useful!
     
  17. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    I love physics and it is awesome to be able to write "Physically inspired" simulations of particles that run entirely in a background thread on code compiled with Burst.
    Setting playback speed works, thanks a lot!

    One issue: It appears that if I access rotationalSpeeds I get three nulls.
    I have been able to work around it by updating the rotation myself, but I thought that I would mention it.
    Ideally, we could use quaternions (three elements, leaving out w and inverting if negative) and/or a more traditional angular velocity vector or possibly angular momentum (which is constant even with varying principal axes of inertia), but that is low priority.
     
  18. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    This is tricky - some attributes only exist if required by the built-in modules. This particular one only exists if using the Rotation modules.

    We have no way currently to say "hey, but I want to use it in my particle job!". I'm open to ideas on how to achieve that - maybe it's as simple as a new script API to request attributes to be allocated.

    One attribute you can force to exist is the custom data. If you call SetCustomParticleData (just once per system, at startup) with some dummy data, you'll have up to 8 floats per particle to play with in your particle job.
     
  19. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    That makes sense, thanks!
    It is fine as it is, no sense in adding extra overhead or complexity if it can get it so easily.
    I would just add comments to let people know.
    Best,
     
    richardkettlewell likes this.
  20. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    Great - I'd love to see what you're using the system for at some point - once you get to a point where you want to show it off! :)
     
  21. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    To clarify, if simulation speed goes below a certain threshold (0.001) OnParticleUpdateJobScheduled() is still called but the job never runs.
    Using 0.001 is "good enough" but it would be a nice extra to have less execution overhead when it is effectively zero.
     
  22. DavidSWu

    DavidSWu

    Joined:
    Jun 20, 2016
    Posts:
    183
    We are doing CFD simulation for water in a SandBox type game. The goal is to enable two-way interactivity between the water and general physical objects (i.e. players, the environment, ais, etc), through a robust simulation.
    We don't use open-loop, techniques such as recomputed playback, noise, or procedurals, as these techniques are difficult to make interactive.

    The Basic system is eulerian (i.e. a sparse 2d grid modeling the height, velocity, temperature, and pressure of the water at staggered sample points). This is great for high performance, low-frequency simulation.

    TLDR: In order to visualize the high-frequency properties of the water (such, splashes, foam, high-frequency ripples, etc) we use particles. We define the model through the particles in question, emit them as appropriate and simulate them based on the environment and the surface and velocity of the water.
    For example, we also simulate things like debris using particles with a simple buoyancy model.

    We considered using sparse 3d grid structures and hierarchical grid schemes, but in the worst case (which will always turn up when the player gets their hands on the controls) these methods get very ugly very fast.
     
    richardkettlewell likes this.
  23. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,374
    I'm not seeing this problem. I just tried the following script on a default particle system and it worked fine:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.ParticleSystemJobs;
    3.  
    4. [RequireComponent(typeof(ParticleSystem))]
    5. public class NewBehaviourScript : MonoBehaviour
    6. {
    7.     ParticleSystem m_ParticleSystem;
    8.     UpdateParticlesJob m_Job = new UpdateParticlesJob();
    9.  
    10.     void Start()
    11.     {
    12.         m_ParticleSystem = GetComponent<ParticleSystem>();
    13.         m_ParticleSystem.Simulate(2.0f);
    14.         m_ParticleSystem.Play();
    15.  
    16.         var main = m_ParticleSystem.main;
    17.         main.simulationSpeed = 0.0f;
    18.     }
    19.  
    20.     void OnParticleUpdateJobScheduled()
    21.     {
    22.         m_Job.m_Time = Time.time;
    23.         m_Job.Schedule(m_ParticleSystem);
    24.     }
    25.  
    26.     //[BurstCompile] // Enable if using the Burst package
    27.     struct UpdateParticlesJob : IJobParticleSystem
    28.     {
    29.         public float m_Time;
    30.  
    31.         public void Execute(ParticleSystemJobData particles)
    32.         {
    33.             var sizes = particles.sizes.x;
    34.  
    35.             for (int i = 0; i < particles.count; i++)
    36.                 sizes[i] = Mathf.Sin(m_Time) + 1.0f;
    37.         }
    38.     }
    39. }
    40.  
    Is your system paused, perhaps? that stops the update + c# job running.
     
unityunity