dimforge / rapier.js

Official JavaScript bindings for the Rapier physics engine.
https://rapier.rs
Apache License 2.0
390 stars 55 forks source link

Comparison still exist with ammo.js and others? #19

Open darzu opened 3 years ago

darzu commented 3 years ago

I found this old reddit thread: https://www.reddit.com/r/javascript/comments/hn0vd2/i_started_writing_a_testbed_to_compare/ from (presumably) @sebcrozet which states that you were putting together a comparison with "Ammo.js/Cannon.js/Oimo.js/PhysX-js". The link now 404s. Is this comparison still around?

I'm currently evaluating .js physics engines for use in a beginner-friendly online game maker, and this is exactly the sort of comparison I was hoping to find.

LeXXik commented 3 years ago

Yes, there was a testbed before, but after the Rapier engine got updated, the testbed was not, so at the moment it only has Rapier engine in it. Not really a comparison testbed, but more like a Rapier demo now I guess.

All of the engines have their components, which together solve a physical state of the bodies. Some components could be faster in one engine, while the others could be slower. I don't think there is a per-compoenent comparison available anywhere. At least I am not aware of one. You also have to consider the features you would need, as some of the engines are younger than the others or distributed in a format not compatible for your target environment. For example, Rapier has no vehicle body simulations, like Bullet (Ammo), but you might not need a vehicle simulation. Or PhysX having it, do not expose it in Wasm, which is pretty limited today due to it being pretty new, etc.

From internal tests for overall performance Rapier is close to PhysX, when run on CPU (no GPU support yet). I think they have the performance data on their blog: https://dimforge.com/blog/2020/08/25/announcing-the-rapier-physics-engine It also outperforms Ammo due to it being AoSoA SIMD optimized for the solver, which allows to solve 4 constraints at a time, while Ammo (Bullet) SIMD optimizes each constraint individually. Plus they use different algos for broad/narrow phase filtering, which could potentially speed it up in comparison.

Apart from it, I am only aware of this one, which has Cannon vs Ammo vs PhysX: https://2ba77ff724a446bfad8715d24bb9cd30.us-west-2.sumerian.aws/

darzu commented 3 years ago

Thank you, that's very helpful!

If I can pry a little more... do you happen to know if there is any significant overhead that comes from calling into WASM-based frameworks from JS vs. JS native frameworks? E.g. if I'm running game logic on collisions or other events, is there some point at which the JS<->WASM becomes costly or is that a non-issue?

Further, I've been looking at babylon.js and wondering if a rapier plugin would be a good fit.

LeXXik commented 3 years ago

There is JS <> Wasm communication overhead, but it is not significant to be concerned about, unless you are fighting for some microseconds in your frame budget. The much more significant overhead is between the main thread and the worker thread, if your Wasm runs in the web worker. If you go that way, then you'd want to group all your frame commands and send it as a single message to the worker, where the commands would be parsed and applied to the physics world. That is instead of sending each command individually.

It also matters where the program will run. For example, I made a little ballistics library, which I used in one of my PlayCanvas games: https://github.com/LeXXik/ballistics From my experience, JS engines (I mean the engine that runs Javascript, like V8) today became pretty smart in optimizing the JS code. I did some small comparison tests with my library and the performance was almost the same between JS and Wasm in the browser, often JS was running even faster. On the other hand, in Node.js the Wasm performance was way better than JS. The library is super simple though, so can't really justify it. You will get significant improvements in performance using physics running in Wasm, because it can leverage SIMD instructions, where JS cannot.

Regarding Babylon - go for it. I'm pretty sure any game engine would benefit from Rapier, which is light, fast and modern. I did Rapier integration with PlayCanvas, but it is private currently, so cannot share.

darzu commented 3 years ago

Thanks again! This is helping me piece everything together.

Looks like I'll need to dig into the architecture of typical Babylon games to see how worker batching will or won't fit. Intuitively it seems likely I should be able to buffer commands. Your point about SIMD is interesting and I hadn't considered that. I wonder if JS physics engines could get large speed ups by moving just some core operations into WASM-SIMD.

Just musing here, but since Rapier is native and portable, I wonder if it'd be possible to setup a project such that it uses JS/WASM bindings in the browser but directly uses native/rust bindings when run natively.

Since you seem to know a bit about PlayCanvas, do you have thoughts on how that compares with BabylonJS for beginner-friendly game dev? BabylonJS seems a little more feature rich and seems to have a little more focus on native exports (incl translation for DirectX/Metal/OpenGL), which seemed appealing, but I'm pretty new to this space.

LeXXik commented 3 years ago

Sorry, I'm afraid I am not familiar enough with BabylonJS to give a comparison. Anyhow, this is going offtopic and you probably better ask that on Babylon/PlayCanvas forums.