Announcing the Rapier physics engine
We are thrilled to announce the release of Rapier. It is a set of two pure-rust libraries rapier2d and rapier3d for 2D and 3D physics engines targetting games, animation, and robotics. Rapier is the successor of nphysics and focuses on performances first.
This post will be quite long, so here is a small table of contents:
- Presenting Rapier
- Rapier for the web
- 3D Benchmark: Rapier vs. PhysX vs. nphysics
- 2D Benchmark: Rapier vs. Box2D vs. nphysics
- Running the benchmarks yourself
- Conclusion
Presenting Rapier
Rapier is the new physics engine I have been working on secretly during the past 5 months. Just like nphysics it is split into two crates: rapier2d and rapier3d for 2D and 3D physics respectively. It is designed to be fast and multithreaded right from the beginning. It is also designed to require less incremental compilation times because the data structures it defines are not generic.
Rapier runs 5 to 10 times faster than nphysics, making it close to the performances of (the CPU version of) NVidia PhysX and faster than Box2D. Benchmarks will be provided in my next blog post.
In addition, Rapier aims to be cross-platform, including web targets. That's why I am maintaining JavaScript bindings right from the beginning. NPM packages already exist: @dimforge/rapier3d and @dimforge/rapier2d.
I am still at the beginning of the implementation of Rapier though, so many features are still missing. However some long-requested features like serialization, (optional) cross-platform determinism, parallelism, and SIMD have already been integrated to ensure their existence and maintenance.
There already are a few key features that makes Rapier stand out. Since they may affect compilation times and/or performances, they are disabled by default and need to be enabled explicitly through cargo features. They are however both enabled on our official NPM packages.
- Serialization: every physics component is serializable using
serde
, meaning you can take a deep snapshot of the physics state and restore it later. This snapshot can even be saved on disk or sent through network. - Cross-platform determinism: if the
enhanced_determinism
feature of Rapier is enabled, you it will behave in a bit-level cross-platform deterministic way in all platforms that comply with the IEEE 754-2008 floating point standard. This means that if you run the same simulation with the same initial states on two different machines (or on a browser) you will get the exact same results. Here "bit-level" determinism means that if you serialize the physics state after the same number of timesteps on two different machines, you will obtain the exact same byte array for both: you may compute a checksum of both snapshots and they will match. All this doesn't apply to platforms with pointer size smaller than 32-bit, and on platforms that don't comply to IEEE 754-2008 strictly.
Rapier for the web
3D Benchmark: Rapier vs. PhysX vs. nphysics
In this benchmark we ran a set of stress tests using three different physics engines:
- Rapier using our rapier3d crate.
- PhysX using the physx crate.
- nphysics using our nphysics3d crate.
Independently from the chosen physics engine, all scenes are always initialized in the exact same way (same bodies, same colliders at the same places). We used the following integration parameters:
- Timestep length: 0.016
- Number of velocity iterations: 4 for Rapier and nphysics, 1 for PhysX.
- Number of position iterations: 1 from Rapier and nphysics, 4 for PhysX.
- Targets: native CPU. (PhysX on GPU has not been benchmarked.)
- Solvers: variations of PGS. (The new PhysX TGS solver has not been benchmarked as it is supposed to be slower.)
A few notes are in order regarding the PhysX benchmark. First, we don't use the same number of iterations for Rapier and PhysX. For Rapier and nphysics we use 4 velocity iterations and 1 position iteration. For PhysX, it is the other way round: 1 velocity iteration and 4 position iterations. This is the most sensible configuration because:
- PhysX developers advise to increase the number of position iterations for better stability, and leave to 1 the number of position iterations.
- PhysX uses 1 velocity iteration and 4 position iterations by default. It yields more stable simulations than using 4 velocity and 1 position.
- Rapier a nphysics use a solver different from PhysX. With our solver, it is recommended to increase the number of velocity iterations instead of position iterations.
The PhysX benchmarks will include two results:
- One result using their default
ePATH
friction model. This is a simplified friction model that is much faster to compute but may generate less realistic stronger friction forces. Rapier and nphysics don't implement a similar model currently. - One result using their
eTWO_DIRECTIONAL
friction model. This is similar to the friction model used by Rapier and nphysics.
Each benchmark in run on two different machines:
- A desktop, running Ubuntu, equipped with an AMD Ryzen 9 3900X CPU, 3.8GHz, 12 cores.
- A MacBook Pro (plugged to a power outlet), running Mac OS, equipped with an Intel Core i7 7920HQ, 3.1GHz, 4 cores.
8.000 stacked balls
3.000 falling boxes
Pyramid of 4.900 boxes
Triangle mesh with 1.500 falling boxes and balls
KEVA planks tower with 5.320 planks
19.800 intereconnected ball joints
20.000 fixed joints
8.000 revolute joints