Search Unity

Resolved Move particles with the wind

Discussion in 'General Graphics' started by Guedez, Jun 28, 2022.

  1. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    Is there a way to move particles with the wind?
    Currently I have a wind system that I use to move grass, trees, crops, etc. It is a cginc that I can import in any vertex shader and it will bend the vertex to the wind.
    But it seems that particles can only be affected by wind zones? I could create a global wind zone and have it set to whatever is the wind at the player position, but that less than optimal. I'd like to query the precise wind information at the particle position, and accelerate it based on that.

    How can I do it? if even possible?

    OBS: The currently implemented wind effect: https://imgur.com/a/XHzcPQ3
     
  2. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    How is your wind system stored and updated? If it’s in a cginc file does that mean it’s all on the GPU?

    the particle system is simulated on the CPU. So i can think of 2 options, but both require that scripts can access your wind:

    1. Write a script that uses Get/SetParticles and update the particles by reading your wind system

    2. Write a C# job, ideally using Burst, to move the particles with the wind. This requires your wind to be stored in a way that can be passed to c# jobs.
     
  3. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    You can move particles using burst without using the Get/SetParticles API? I was not aware of that. The wind calc is currently GPU only, but it would be trivial to make a Burst version of it.

    Edit: After a bit of googling I believe I figured out how, but I still have one question: Can I also spawn particles through a burst job?
     
    Last edited: Jun 29, 2022
  4. richardkettlewell

    richardkettlewell

    Unity Technologies

    Joined:
    Sep 9, 2015
    Posts:
    2,285
    You can't spawn particles in the c# job, only update them.

    If you do something like:

    Code (CSharp):
    1. ps.Emit(100, emitParams);
    where the params sets a property to a magic number, you could detect those in the c# job to know they just spawned. (just be careful it's not a property that the native update might change, eg probably dont use the position as something in the native update is probably moving your particles too)

    Sorry i really ought to have given you some links:

    https://docs.unity3d.com/ScriptReference/ParticleSystem.Emit.html (for emit params example)
    https://docs.unity3d.com/Manual/particle-system-job-system-integration.html
    https://docs.unity3d.com/ScriptRefe...bs.IJobParticleSystemParallelFor.Execute.html (job example code here.. best concurrency is by using parallel for or parallel for batch job types)

    Simulating particles using these c# jobs is *incredibly* efficient compared to using Get/SetParticles on the main thread.
     
  5. Guedez

    Guedez

    Joined:
    Jun 1, 2012
    Posts:
    827
    What a shame, because my grass cutting code happens in c# burst, and it does have the precise position and type of each blade of grass it cuts right then and there (and then gets compressed into total_grass_cut per grass_type to report to whomever cut the grass so he can get loot and exp).
    Some internal stuff happens to make the IJobParticleSystem able to access the particles list, right? Because I think I could have all particles pre spawned and marked as 'dead' or 'inactive', and then the grass cutting code iterates over them to find the first dead/inactive to 'spawn' it.
    This will end up becoming a feature request, but if the particle system were to let us access by c# burst the 'first dead/inactive' particle to 'spawn' it, it would be pretty amazing.