Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Help  Poor performance when enabled surface collision
#1
Hello,

I have a testing scene with one ObiCloth object in it. I need surface collision for the project to make sure that no unexpected object penetrating through this cloth object, however when I turn on surface collisions, the performance become significantly worse, <10 fps. When surface collision is turned off, I can get over 60fps.

Is there a way to improve it?

Another behavior that I'm noticing is that after turning on surface collision the cloth object start to "drifting off" the surface it is placed on.
Reply
#2
(08-09-2022, 07:39 PM)snowtv Wrote: Hello,

I have a testing scene with one ObiCloth object in it. I need surface collision for the project to make sure that no unexpected object penetrating through this cloth object, however when I turn on surface collisions, the performance become significantly worse, <10 fps. When surface collision is turned off, I can get over 60fps.

Is there a way to improve it?

Hi!

Surface collisions are a bit more costly than normal, particle-based collisions. If you're using self-collisions in addition to surface collisions, make sure your particle radius is small, otherwise a lot of self-surface contacts will be generated which can get expensive very quickly.

If that's not the case, you can trade speed for accuracy using the solver's "surface collision iterations" setting: less iterations will yield less accurate, but faster surface collisions. See: http://obi.virtualmethodstudio.com/manua...olver.html

(08-09-2022, 07:39 PM)snowtv Wrote: Another behavior that I'm noticing is that after turning on surface collision the cloth object start to "drifting off" the surface it is placed on.

What collision material settings are you using? is there any friction between the cloth and the surface?

let me know how it goes!

kind regards,
Reply
#3
(09-09-2022, 10:07 AM)josemendez Wrote: Hi!

Surface collisions are a bit more costly than normal, particle-based collisions. If you're using self-collisions in addition to surface collisions, make sure your particle radius is small, otherwise a lot of self-surface contacts will be generated which can get expensive very quickly.

If that's not the case, you can trade speed for accuracy using the solver's "surface collision iterations" setting: less iterations will yield less accurate, but faster surface collisions. See: http://obi.virtualmethodstudio.com/manua...olver.html


What collision material settings are you using? is there any friction between the cloth and the surface?

let me know how it goes!

kind regards,
 
Hello!

I've done some more tests today, I think the collision material does affect the physics pretty significantly. I also found out that the surface collision can easily cause the solver to basically "freeze", I'm guessing it's because of the self-surface contacts you mentioned. I think it make sense that when surface collision is turned on, the particle radius should be reduced as surface collision should prevent penetration.

In case I end up not using surface collision due to its impact on the performance, I want to know a bit more about the blueprint creation process for ObiCloth. I'm a bit confused about the amount of particles created in relate to the complexity of the cloth mesh. It looks like the blueprint will create one particle for each indices in the mesh data, but is that really necessary? Because the actual vertex count is much less, as many indices are shared between the triangles.

I mainly want to optimize the performance. I currently have a mesh object with around 9k indices (but it actually has only 1.5k vertices), and I need two instances of them in my simulation. When there is only one instance the fps is around 40, which is good enough, but when I enable two of them, the fps suddenly drops to around 10, which is not usable. I wonder why the performance drops 4 times, there are no contacts between the two instances, either.
Reply
#4
(09-09-2022, 09:33 PM)snowtv Wrote:  
In case I end up not using surface collision due to its impact on the performance, I want to know a bit more about the blueprint creation process for ObiCloth. I'm a bit confused about the amount of particles created in relate to the complexity of the cloth mesh. It looks like the blueprint will create one particle for each indices in the mesh data, but is that really necessary? Because the actual vertex count is much less, as many indices are shared between the triangles.

Obi does not create one particle for each entry in the mesh indices array, as that would create a lot of
duplicate particles. It merges spatially close vertices, and then creates one particle per merged vertex. Then for each original vertex, it stores the index of the particle associated to it. Multiple vertices can share the same particle. This map is stored in the blueprint’s topology (a half-edge structure), in an array named “rawToWelded”.

During particle creation, triangle indices (connectivity) are largely ignored. They’re only used for constraint creation.


(09-09-2022, 09:33 PM)snowtv Wrote: I mainly want to optimize the performance. I currently have a mesh object with around 9k indices (but it actually has only 1.5k vertices), and I need two instances of them in my simulation. When there is only one instance the fps is around 40, which is good enough, but when I enable two of them, the fps suddenly drops to around 10, which is not usable. I wonder why the performance drops 4 times, there are no contacts between the two instances, either.

If there’s 9000 triangle indices and 1500 vertices, Obi will create 1500 particles max, usually less than that since your mesh will have uv/normal/color seams which Obi will weld before creating particles.

Have you tried using the profiler to determine the bottleneck? It sounds like death spiralling to me, could it be that the entire physics loop is being performed 4 times each frame?

Take a look at the profiler if you haven’t yet, I can help you interpret its information if you need.

Kind regards,
Reply
#5
(10-09-2022, 08:44 AM)josemendez Wrote: Obi does not create one particle for each entry in the mesh indices array, as that would create a lot of
duplicate particles. It merges spatially close vertices, and then creates one particle per merged vertex. Then for each original vertex, it stores the index of the particle associated to it. Multiple vertices can share the same particle. This map is stored in the blueprint’s topology (a half-edge structure), in an array named “rawToWelded”.

During particle creation, triangle indices (connectivity) are largely ignored. They’re only used for constraint creation.



If there’s 9000 triangle indices and 1500 vertices, Obi will create 1500 particles max, usually less than that since your mesh will have uv/normal/color seams which Obi will weld before creating particles.

Have you tried using the profiler to determine the bottleneck? It sounds like death spiralling to me, could it be that the entire physics loop is being performed 4 times each frame?

Take a look at the profiler if you haven’t yet, I can help you interpret its information if you need.

Kind regards,

I'm getting 9k "used particles" in the solver when I have one active cloth actor under it, is it because I'm using the TearableCloth? I do see it drops to 1.5k when switch to non-tearable cloth.

I also got better results with surface collision after I reduced the particle size when generating the blueprint, however, the surface collision is definitely not "perfect". In my project there will be very pointy objects that will be interacting with the cloth mesh, and they seem to still penetrating the mesh if moving fast enough. Another big issue is that if the cloth is squeezed between two colliders, it will go into a sort of "death spiraling" and can't stop jittering and destroy the performance.

Currently I'm thinking about a way to "cheat" the collision, by adding a temporary pin constraint when my pointy tools collide with the cloth, so the cloth particle is basically attached to the tool, and I'm thinking to check the tool's movement vector against the pinned particle's normal, to remove the pin constraint when the tool is not moving towards the cloth object. Has anybody tried that before?
Reply
#6
(13-09-2022, 08:30 PM)snowtv Wrote: I'm getting 9k "used particles" in the solver when I have one active cloth actor under it, is it because I'm using the TearableCloth? I do see it drops to 1.5k when switch to non-tearable cloth.

Tearable cloth preallocates enough particles to deal with the case that a given percentage of edges are torn (by default, all edges) without any runtime memory allocation. Most these particles start as inactive, and get activated as the cloth is torn and new particles are required. This doesn’t mean all 9000 particles are part of the simulation, only that memory has been allocated for them.

Regulat cloth cannot be torn, so it does not preallocate any extra particles.

(13-09-2022, 08:30 PM)snowtv Wrote: I also got better results with surface collision after I reduced the particle size when generating the blueprint, however, the surface collision is definitely not "perfect". In my project there will be very pointy objects that will be interacting with the cloth mesh, and they seem to still penetrating the mesh if moving fast enough.

Surface collisions are not “perfect” by any means, they’re just an approximation of full geometry collision detection which is extremely expensive (detecting and solving all vertex-vertex, edge-edge and triangle-vertex contacts). This approximation treats triangles as simplices and assume only 1 contact point per simplex-object pair. Contact information is also iteratively arrived at, so it isn’t 100% correct either: you can trade performance for accuracy by changing the amount of “surface collision iterations” in the solver component.

While surface collisions can be regarded as a form of spatial supersampling, they don’t perform any kind of temporal supersampling. So they won’t improve continuous collision detection against fast moving objects in any way. If you want finer temporal resolution, increase the amount of substeps.

(13-09-2022, 08:30 PM)snowtv Wrote: Another big issue is that if the cloth is squeezed between two colliders, it will go into a sort of "death spiraling" and can't stop jittering and destroy the performance.
What is your solver’s “max depenetration” velocity setting, and which update mode (sequential or parallel) are you using for collision constraints?

Quote:Currently I'm thinking about a way to "cheat" the collision, by adding a temporary pin constraint when my pointy tools collide with the cloth, so the cloth particle is basically attached to the tool, and I'm thinking to check the tool's movement vector against the pinned particle's normal, to remove the pin constraint when the tool is not moving towards the cloth object. Has anybody tried that before?

This is a good idea if you require very precise collision detection against very thin objects, moving at arbitrarily large speeds. Its also how picking/grabbing objects is implemented in pretty much all games: picking generally does not rely on physical contact calculations because by the time you get accurate enough interaction by cranking parameters up, collision detection becomes extremely expensive and can never be as robust as kinematically pinning/fixing/attaching two objects.

The included utility script “ObiContactGrabber” does this, but instead of being velocity based it exposes two public methods Grab() and Release() that allow you to grab and release any particles in contact with a given collider.
Reply
#7
(14-09-2022, 06:06 PM)josemendez Wrote: Tearable cloth preallocates enough particles to deal with the case that a given percentage of edges are torn (by default, all edges) without any runtime memory allocation. Most these particles start as inactive, and get activated as the cloth is torn and new particles are required. This doesn’t mean all 9000 particles are part of the simulation, only that memory has been allocated for them.

Regulat cloth cannot be torn, so it does not preallocate any extra particles.


Surface collisions are not “perfect” by any means, they’re just an approximation of full geometry collision detection which is extremely expensive (detecting and solving all vertex-vertex, edge-edge and triangle-vertex contacts). This approximation treats triangles as simplices and assume only 1 contact point per simplex-object pair. Contact information is also iteratively arrived at, so it isn’t 100% correct either: you can trade performance for accuracy by changing the amount of “surface collision iterations” in the solver component.

While surface collisions can be regarded as a form of spatial supersampling, they don’t perform any kind of temporal supersampling. So they won’t improve continuous collision detection against fast moving objects in any way. If you want finer temporal resolution, increase the amount of substeps.

What is your solver’s “max depenetration” velocity setting, and which update mode (sequential or parallel) are you using for collision constraints?


This is a good idea if you require very precise collision detection against very thin objects, moving at arbitrarily large speeds. Its also how picking/grabbing objects is implemented in pretty much all games: picking generally does not rely on physical contact calculations because by the time you get accurate enough interaction by cranking parameters up, collision detection becomes extremely expensive and can never be as robust as kinematically pinning/fixing/attaching two objects.

The included utility script “ObiContactGrabber” does this, but instead of being velocity based it exposes two public methods Grab() and Release() that allow you to grab and release any particles in contact with a given collider.

Thanks for the feedback! I've thought about another alternative to the "cheat" method I mentioned in the last post. The alternative I'm thinking is to create Unity mesh colliders at the potential point of collision, then blocks the potential penetration using Unity's collision physics. But I'm not sure which of these two methods is more reliable/easier to implement/easier to tweak.

I'll try to explain the mesh collider method:

for each potential contacting point, create a collision cluster

one cluster is consist of several overlapping flat mesh colliders formed from an area of particles, where the most overlapped area is the most likely point of collision with the potential contact point

each collider should have a trigger which size is a bit larger, when a collider enters the trigger, that collider should "harden" itself and stop deforming with its corresponding cloth particles, and attach the particles to its vertices using pin constraint

when the particles in a cluster "bends" beyond an angle threshold, all the mesh colliders in this cluster should "harden", which will stop the deformation of all the particles in this collider by pinning them to the mesh colliders
Reply