Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

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,625
    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. Deleted User

    Deleted User

    Guest

    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,625
    Yes :)

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

    KokkuHub

    Joined:
    Feb 15, 2018
    Posts:
    428
    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,625
    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:
    121
    Hello!
    Where and when Particle System Jobs would be available in public build?
     
  7. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,625
    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:
    121
    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:
    698
    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!
     
    lclemens likes this.
  10. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    121
    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,625
    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,625
    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,502
    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:
    121
    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,625
    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,625
    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,625
    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,625
    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.
     
  24. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    384
    Unity3d 2019.3.9f1

    When I inherit from IJobParticleSystemParallelFor
    I'm missing job.Schedule(ParticleSystem)

    Should I include some special extension ?
     
  25. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,625
    It should just work. Do the example scripts work? Eg the post above yours.
     
  26. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    384
    OK I have found the problem.
    The only thing that makes me a little less ashamed of myself are misleading error and the fact that you have not found error in my post :).
    Basically for IJobParticleSystemParallelFor we have to use job.Schedule(ParticleSystem,int) or else it will give use error that it cannot convert from ParticleSystem to JobHandle.
     
    richardkettlewell likes this.
  27. thebarryman

    thebarryman

    Joined:
    Nov 22, 2012
    Posts:
    76
    @richardkettlewell I've been playing around with the ParticleSystem jobs and they are really great! One thing I'd like to be able to do is kind of a post-process pass on the particles but am having a tough time with it. Basically the idea is akin to a vertex shader that operates on the particle itself (so it affects rendering/bounds/billboarding etc) but doesn't affect the underlying sim.

    My thought is that the best way to do it would be to cache some things in custom data, but even that doesn't seem like it gets me exactly where I want because the job always runs after the native particle update. What I'd like to do seems like it might need to run one job before the native update, and then another job after. Something like -

    Remove render offsets from last frame stored in custom data
    Run native simulation
    Add render offsets for this frame, store in custom data

    Do you have any thoughts on other ways this could be accomplished?
     
    Last edited: Apr 16, 2020
  28. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,625
    Can you use a vertex shader?
     
  29. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    121
    Hello, I've same problem as koirat, Schedule(ParticleSystem,int) is not found, but my Unity 2019.2.2f1 version. Can I use ParticlesJobs at this version?
    richardkettlewell

    EDIT: found, at this version I should use ParticleSystem.SetJob(job)
     
    Last edited: Apr 22, 2020
  30. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,625
    The support is still only experimental in 2019.2, so its using the old API. It's final in 2019.3. I left the old experimental API example on the release page so you can see both methods: https://forum.unity.com/threads/release-particle-system-c-job-system-support.529284/
     
    mitaywalle likes this.
  31. mitaywalle

    mitaywalle

    Joined:
    Jul 1, 2013
    Posts:
    121
    richardkettlewell likes this.
  32. thebarryman

    thebarryman

    Joined:
    Nov 22, 2012
    Posts:
    76
    The reason not to use a vertex shader would be to leverage the internal particle functionality, like the way the particle system updates its local bounds, billboards to the camera, can have trails following, etc. But I understand it's not how the job system was designed.
     
  33. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,625
    Ah, apologies, i failed to properly read your original message!

    Hmm I can’t think of a good way to accomplish this.

    The only thing I can think of involves SetParticles on the main thread..

    So the c# job would modify the particles, but store the original properties to a NativeArray first (could do it with a job chain, or do it all in one job)

    Then in the Update of the monobehaviour, pass the array to SetParticles, to restore it to its previous state.
     
    thebarryman likes this.
  34. thebarryman

    thebarryman

    Joined:
    Nov 22, 2012
    Posts:
    76
    Cool, thanks for your answer!
     
    richardkettlewell likes this.
  35. Pimpace

    Pimpace

    Joined:
    Sep 21, 2017
    Posts:
    41
    Hey!

    Is there a way to draw a line to connect two particles? I got how to manipulate all the particles with IJobParticleSystemParallelFor, but I need to connect them with a LineRenderer (maybe a prefab). Without a JobSystem it's easy, but not very performant if we have more thousand particles.
    Is there a way to achieve this? Pass a LineRenderer data to a native array or something?
    The benefit would be here if we can iterate all particle, make calculations then put the position[0] and [1] back to LR to connect two particles. But can I access a LineRenderer object in a job thread?
     
  36. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,625
    You can't access a LineRenderer in a job.

    You can build a NativeArray of line segments in the job, then decide how to render them.

    I've written an example here that connects nearby particles - you could take a look at it for inspiration:
    https://forum.unity.com/threads/particle-system-c-job-system-support.529284/#post-4733855

    It has a fairly heavy main thread part to be able to draw the lines, due to current restrictions about how you render things from script with Unity. But it's the best we can do at the moment.
     
  37. Pimpace

    Pimpace

    Joined:
    Sep 21, 2017
    Posts:
    41
    Thanks sir, I appreciate it. I'll definitely make some experiment and report back here.
     
    richardkettlewell likes this.
  38. XaneFeather

    XaneFeather

    Joined:
    Sep 4, 2013
    Posts:
    90
    Are the particle jobs supported on mobile yet? I just tested running my particle jobs (IJobParticleSystemParallelFor) in an Android build and it crashes immediately upon emitting. Is there any way to debug this on my end? I am using Unity 2020.1f1.
     
    Last edited: Sep 21, 2020
  39. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    1,625
    Yes.

    If Burst is supported on your platform, then the particle jobs can run really fast using Burst. But if not, you can remove the BurstCompile attribute to hopefully make them work.

    EDIT: this page says it’s supported for arm v7 and v8+: https://docs.unity3d.com/Packages/com.unity.burst@latest/manual/index.html
     
  40. XaneFeather

    XaneFeather

    Joined:
    Sep 4, 2013
    Posts:
    90
    Thanks, sadly I've already tried removing Burst entirely, I think the issue is somewhere else as it crashes exactly upon emission still. There's actually no information thrown back onto Unity that helps me debug this so I wonder if there are any tools I might be missing here. I've tried the LogCat browser but it too does not give me any stacktrace at all. I might try going with a simpler particle test or use a different job type and see if I can find what's causing this. It works just fine in the editor and in Windows builds.
     
    richardkettlewell likes this.
unityunity