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.

rapier logo

This post will be quite long, so here is a small table of contents:

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.

  1. 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.
  2. 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:

  1. Rapier using our rapier3d crate.
  2. PhysX using the physx crate.
  3. 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:

  1. 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.
  2. 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:

  1. A desktop, running Ubuntu, equipped with an AMD Ryzen 9 3900X CPU, 3.8GHz, 12 cores.
  2. 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

bench balls bench balls bench balls

3.000 falling boxes

bench boxes bench boxes bench boxes

Pyramid of 4.900 boxes

bench pyramid bench pyramid bench pyramid

Triangle mesh with 1.500 falling boxes and balls

bench trimesh bench trimesh bench trimesh

KEVA planks tower with 5.320 planks

bench balls bench keva tower bench keva tower

19.800 intereconnected ball joints

bench balls bench ball joints bench ball joints

20.000 fixed joints

bench fixed joints bench fixed joints bench fixed joints

8.000 revolute joints

bench revolute joints bench revolute joints bench revolute joints

2D Benchmark: Rapier vs. Box2D vs. nphysics

Running the benchmarks yourself

Conclusion