Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Scripting sleeping particles
#1
Hey there,

I'm trying to build a big underwater kelp forest and for this I experimented with having the big kelp as obi cloth actors.
Each of them are around 500 particles so I'm planning to have maximum up to 10 active at any moment.
The sleep threshold on the solver is always at 0 so they move themselves within the turbulent water.

How can I tell the Burst-Backend solver which particles are sleeping and which active and to ignore the sleep threshold?
 
Already tried disabling ObiClothRenderer but that just stops the rendering and still simulates the particles it seems.
Next thing to try is one solver per Kelp but I'm guessing performance will tank and they won't interact with each other this way.
Is there a simpler solution I havent found yet?
Reply
#2
(07-12-2020, 03:22 PM)ibbybn Wrote: Hey there,

I'm trying to build a big underwater kelp forest and for this I experimented with having the big kelp as obi cloth actors.
Each of them are around 500 particles so I'm planning to have maximum up to 10 active at any moment.
The sleep threshold on the solver is always at 0 so they move themselves within the turbulent water.

How can I tell the Burst-Backend solver which particles are sleeping and which active and to ignore the sleep threshold?
 
Already tried disabling ObiClothRenderer but that just stops the rendering and still simulates the particles it seems.
Next thing to try is one solver per Kelp but I'm guessing performance will tank and they won't interact with each other this way.
Is there a simpler solution I havent found yet?

Hi ibbybn!

Sleeping particles do not reduce the solver's workload in any way.
http://obi.virtualmethodstudio.com/tutor...olver.html

Quote:Any particle with a kinetic energy below this value will be freezed in place. This is useful when you don´t want minuscule variations in velocity or force to perturb an actor, making it look like its jittering or moving very slowly.

Sleeping does not work the way it does in a rigidbody engine. Rigidbody engines typically look for "islands" of interconnected rigidbodies that aren't constrained to any rigidbody outside their island. When all rigidbodies in the island are below a kinetic energy threshold, the entire island is excluded from all simulation steps except for collision detection (as collisions can cause the island to wake up again).

In Obi, particle positions are simply not updated if the kinetic energy of the particle is below the sleep threshold. This hides any jittering or unwanted positional drift due to very small forces. However, for all intents and purposes the particle is still simulated and included in any constraints.

Quote:Next thing to try is one solver per Kelp but I'm guessing performance will tank and they won't interact with each other this way.

One solver per kelp is fine in terms of performance. A solver generates a list of simulation tasks that must be performed. Unity's job system (if using Burst) or Obi's job system (if using Oni) will simulate all pending tasks for the frame (in parallel when possible) regardless of which solver originated them.

But, you're right that kelp algae in different solvers won't interact with each other :/.


Personal opinion: using full cloth simulation for kelp might be a bit overkill, depending on how many of them you need. Using procedural simulation in a vertex shader would be a much more efficient approach imho.
Reply
#3
Thinking a bit more about your use case, came up with a relatively simple fix that will allow you to deactivate the ObiCloth component while leaving the mesh visible.

Open up ObiClothRendererMeshFilter.cs, and remove or comment out line 48:

Code:
protected override void OnBlueprintUnloaded(ObiActor actor, ObiActorBlueprint blueprint)
        {
            clothMesh = null;
            //filter.sharedMesh = null; //<--- remove or comment this
        }

This will prevent the mesh from being removed from the mesh filter when disabling cloth, effectively allowing you to keep the mesh visible while disabling simulation. I'm thinking of including this small change in next updates.
Reply
#4
Hey, thx for the quick responses!

Yes I indeed thought sleeping meant less workload. I'll try out commenting out that line to get the interaction between the cloths back. I have since implemented the one solver per kelp and added a simple manager turning their fixed updaters on and off depending on their distance and a max solver active limit. Works pretty well.
I already have procedural animation for all the low to the ground flora but for the kelp that's not possible since in my game you can push them aside with a sub and the kelp would just clip through. It also looks way more interactive this way.
Can get up to 20 solvers with now 365 particles each in and then performance seems to nosedive pretty sharply.
Will report back how the other fix works out!
Reply
#5
Commenting out the line and then toggling on/off the ObiCloth component in editor works. Nice!
However, I'm a bit stumped that when toggling it via script in there's a glitch ( to their rest position? ) for one frame. Any ideas?
Already tried in Update and LateUpdate and changing the Script Execution Order of the fixed late updater vs my clothtoggler. Odd.
Reply
#6
(10-12-2020, 11:20 PM)ibbybn Wrote: I already have procedural animation for all the low to the ground flora but for the kelp that's not possible since in my game you can push them aside with a sub and the kelp would just clip through. It also looks way more interactive this way.

Passing the sub's world space position to the kelp shader and simply applying vertex displacement based on distance to the sub can look quite nice and is extremely cheap. I don't know if you've ever played overcooked before, the trees in the stage selection map wobble using this method:
https://www.youtube.com/watch?v=66u0FiSZjG4

Edit: same technique used here: https://www.youtube.com/watch?time_conti...vbZ5NDDyTU

Don't know about the specifics of your game though, this is just a suggestion.

(10-12-2020, 11:20 PM)ibbybn Wrote: Can get up to 20 solvers with now 365 particles each in and then performance seems to nosedive pretty sharply.
Will report back how the other fix works out!

Once the wall clock time it takes to render a frame is roughly above the timestep length, the engine can enter death spiraling. In that case performance will degrade a lot, very quickly. The usual fixes apply in this case: larger timestep, smaller max fixed timestep.
Reply
#7
(11-12-2020, 01:58 AM)ibbybn Wrote: Commenting out the line and then toggling on/off the ObiCloth component in editor works. Nice!
However, I'm a bit stumped that when toggling it via script in there's a glitch ( to their rest position? ) for one frame. Any ideas?
Already tried in Update and LateUpdate and changing the Script Execution Order of the fixed late updater vs my clothtoggler. Odd.

Not able to get this to happen :/. As soon as you deactivate the cloth, the mesh stops being updated (this usually happens in LateUpdate()) and just sits there to be rendered by the MeshRenderer. Should be no reason for it to return to its rest position for one frame. Can you share the code you're using?
Reply
#8
Yes that looks like spherical procedural animation. I tried that with the big kelp and it just didn't look convincing. It's not a topdown cartoonish game so you can see it from very near and it looks very stretched with a big sub.

Performance seems managable so far. I can keep the turned off clothes moving with a simple wind vertex displacement shader.

Turns out that using ObiFixedUpdater and turning the cloth on/off in Update() DOES work after all. So all is good.
If you want to see the glitch use the ObiFixedUpdater and turn on the cloth in LateUpdate after it was off.
I'll just complete the job handle in late update anyway and switch the clothes the next frame.
Reply