gkjohnson / three-mesh-bvh

A BVH implementation to speed up raycasting and enable spatial queries against three.js meshes.
https://gkjohnson.github.io/three-mesh-bvh/example/bundle/raycast.html
MIT License
2.56k stars 268 forks source link

Performance questions about `characterMovement` #455

Closed krispya closed 2 years ago

krispya commented 2 years ago

Thank you for this amazing package. I am using the characterMovement example as the base for a custom character controller and currently looking at ways to optimize the collision loop, especially when doing multiple iterations per frame. I am just learning a lot of these concepts and saw that there is an opportunity with interesectsRange to possibly bail out early but I don't understand how to implement this. Could you give me a code example or explain how to use this check?

Any other optimization suggestions for the characterMovement collision loop would also be greatly appreciated!

gkjohnson commented 2 years ago

Thanks! Glad you're getting some use out of it. Why do you believe intersectsRange might provide you a performance benefit here? And what kind of performance issues are you seeing with the character movement collision loop?

krispya commented 2 years ago

To be honest, I was looking for a way to bail out of triangle search early and thought instersectsRange might help. I did not know enough about it to know if that was true so I decided to ask! :)

Right now I'm attempting to profile the difference between the loop in your characterMovement example and mine even though they have very similar code and I'm starting to think it might have to do with the collider BVH itself. Firefox shows the most stark difference with your example's loop being 2-3ms while mine is ~11ms with 5 iterations. It looks like it is doing a lot more searching for me. I'll get a 1 to 1 test together before bothering you further.

gkjohnson commented 2 years ago

Unfortunately you cannot early out of the loop when performing the search for this kind of physics sim. The collider must be adjusted by every contact it has with each triangle. In terms of the difference in time - the complexity and density of the mesh will play a big role. There's a reason that most games use a simplified geometry for physics and collisions rather than the high detail version.

krispya commented 2 years ago

Thanks that makes a lot of sense and gave me some ideas for issues to check. I am happy to say I found the culprit to my performance woes and also came away with a few tips that I'll leave for others who might be interested in the same idea.

First my hilarious problem: Make sure your intersectBounds is intersecting the right bounding box! I had accidentally named both the collider aabb and character aabb box so the statement looked like intersectsBounds: (bounds) => bounds.intersectsBox(box). This meant my physics was intersecting every triangle in the collider every frame! A positive I can say about this is that Chrome holds up very well under this stress test while Firefox does not.

Now some additional tips I found:

Thanks again for the great library.

gkjohnson commented 2 years ago

Great! Glad you figured it out - if you think there are improvements that could be made to the docs or example so it's more clear please feel free to make a PR!