Unity-Technologies / com.unity.demoteam.hair

An integrated solution for authoring / importing / simulating / rendering strand-based hair in Unity.
Other
719 stars 97 forks source link

Limit of 8 colliders is very limiting. #27

Open methusalah opened 1 year ago

methusalah commented 1 year ago

In my game, the hair can be in collision with a lot of different objects, for example :

These objects can collide one another and use primitive colliders instead of mesh colliders for obvious performance reasons. Therefore, the hair can be in contact with hundreds of spheres or capsules simultaneously.

But the demoteam hair asset does not allow more than 8 colliders in total, and only a single SDF. I understand that it is mainly designed to have collisions with the body of the character, but it very limiting. Even a character lying on a bed could not have their hair correctly colliding with a simple pillow that is not primitive shaped. Let alone my own use case when you can actually touch hairs.

As far as I know (being myself the author of the asset HairStudio), allowing hundreds of sphere colliders is completely doable without a massive impact on the performances. Most importantly, one should be able to make the choice of a slower simulation if they need to have a lot of collisions in their game.

Is there a way to lift the limit of 8 colliders somehow?

fuglsang commented 1 year ago

Thank you for the report!

For now the limitation set rather conservatively. When boundaries are not specified specifically, this really acts as an active limit, since boundaries by default are being collected within the hair volume per-frame. I have a small TODO to also prioritize the active boundaries by distance, which unfortunately didn't make it into the initial release.

Pending other more pressing issues, we can take a look at lifting the limitation later. From my perspective, there are some important things to consider in this regard:

methusalah commented 1 year ago

As far as I can tell, the only way you can specify boundaries is in the "Boundaries Priority" list. These boundaries are also affected by the limit of 8 colliders, despite the tooltip stating "Always included boundaries". If I have more than 1 SDF + 7 spheres in this list, some of them will be discarded. I tested it with "Boundaries Collect" on and off with the same result.

Is it the intended result? Is there another way to specify boundaries and have more than 8 of them at the same time?

As a side note, the order of the boundaries in the list does not seem to imply which ones will be discarded. I was expecting the lower elements to be discarded in priority, given the name of the list (but it may be just me ^^).

About the limit itself, I would argue that the game designer is responsible for the number of colliders present in the hair volume simultaneously. Any physics system is expected to be lower and lower the more colliders are involved (or the most complex the colliders' shapes are).

In HairStudio, a trigger sphere collider is spawned around the hair volume and colliders are collected by the physics engine, using the collision matrix only. The game designer only set a layer of the hair to manage collisions. The collider buffer is set to a bigger size every time the maximum number of colliders increases (and is never shrunk). The cost of the primitives is linear (and almost the same for spheres, boxes and capsules), so the game designer can easily predict the performance of the simulation by just checking the maximum number of colliders that are collected in various situations.

In my video game using HairStudio, I often have 300 spheres and it never took more than 15% of the overall simulation time (GPU side). I must add that I don't manage complex friction, bouncing and other, so it may not be comparable.

fuglsang commented 1 year ago

As far as I can tell, the only way you can specify boundaries is in the "Boundaries Priority" list. These boundaries are also affected by the limit of 8 colliders, despite the tooltip stating "Always included boundaries". If I have more than 1 SDF + 7 spheres in this list, some of them will be discarded. I tested it with "Boundaries Collect" on and off with the same result.

Is it the intended result? Is there another way to specify boundaries and have more than 8 of them at the same time?

Correct. Currently there is no way to have more than 8 active boundaries.

There is a related known issue, however, with boundaries in the priority list not actually taking priority over boundaries automatically gathered via overlap query.