JavaScript physics engine

A new physics engine, entirely written in JavaScript.

Live link

A few more examples (links on images):
image
image
image
image
image

I’ve been a fan of Cannon.js physics engine for a long time. It’s a written entirely in JavaScript, it’s tiny and it’s very capable for its size.

I’ve also been a fan of Bullet physics engine, which is an entirely different type of beast, written in C++ and contrasting to Cannon.js, it’s a bells & whistles type of engine. It’s very fast, and it has pretty much everything you could want from a physics engine. But it’s not small and it’s not light. On the web it has a and additional major weakness - it doesn’t run natively. You have to cross-compile it and run it inside a wasm container. So debugging experience and integration are far from perfect.

For a while, I was wondering - could we have a fully featured engine that’s fast, but… like JavaScript?

Over the years, I have built pretty much everything a physics engine would need, except the engine itself. I built an great set of spatial indices that you would need for a fast broad phase, I built a geometry package that you would need for the narrow phase.

A few weeks ago, I decided I would throw my hat in the ring and add first-class physics system into meep and started working on the engine.

Performance

I’m yet to build a like-for-like comparrison, but anecdotally

  • vs Cannon.js - cannon scales linearly and doesn’t sleep well, so it doesn’t scale at all. It doesn’t make any effort to be cache coherent either, so it’s slower on small scenes and it’s much slower on large scenes. Beyond about 300 dynamic bodies it’s no longer real-time.
  • vs Rapier.js (rust engine) - rapier is very capable, but again, it it is less stable. Performance-wise it seems about on-par.
  • vs Ammo (Bullet) - hands down faster, likely less to do with bullet and more to do with the bindings.
  • vs PhysX - same story, PhysX is slower on active solve (lots of things in motion), at least the popular WASM ports.

Stability

A lot of compromises were made in order to achieve determinism and stability. The engine is in the class of its own compared to others here. Anecdotally, if I were to drop all of the correctness and energy preservation machinery that I built into the engine - it would be abut 70% faster on hard cases where perf matters. Instead, the engine makes a lot of trades sacrificing performance to avoid penetrations and energy gain.

One obvious reason why this engine is more stable is use of Float64 for all solver operations. It makes the solver a little slower, especially on mobile, but it automatically resolves a lot of instability on its own.


My recently published First-person character controller also relies on this physics engine.


Cursious to hear thoughts and any form of feedback

4 Likes

As a small anecdote on robustness and performance. Here’s Rapier’s own torture test, the KEVA tower

and here it is after a while

The solver is not capable of resolving the forces properly at the start, which introduces a wobble into the tower and it eventually injects enough energy into the system that the whole tower collapses.

Here’s the same thing in meep

It runs slower at the start, about 40% slower to be exact, but it settles completely and every block goes to sleep.

And we can still destroy the whole thing by shooting some balls at it

This is not an optimization scenario specifically, but I just wanted to emphasize that there’s more than just speed to be considered. And when Rapier touts to be running in WASM, being written in rust and using SIMD - I’m pretty happy with my pure JS physics engine.

5 Likes

so whats the best js physics?