New Physics Plugin for three.js (using ammo.js)

New Physics Plugin for three.js (using ammo.js)

2 month ago I started developing a 3d extension for Phaser called enable3d. It wraps three.js and ammo.js.

This week I spend a lot of time extracting the three and ammo wrappers into their own modules. This is how the physics plugin for three.js was born.


  • Headless mode (runs ammo.js on your node.js server)
  • Add physics to all meshes (also BufferGeometry)
  • Compound Shapes (automatic or manuall)
  • Supports Capsule, Hull, HACD, Convex/Concave Mesh and Heightfield
  • Collision Callbacks
  • Dynamic, Static, Kinematic and Ghost Bodies
  • Constraints
  • CCD Motion Clamping
  • Simple objects Factory


Here are some examples. Only the first example uses native three.js with the physics plugin. But you can do all the things (related to physics) shown in the other examples as well.


You should find all you need in the documentation I wrote.

Quick start guide.

// Use the physics loader to load the right version of ammo.js,
// before starting your scene.
PhysicsLoader('/lib', () => MainScene())

// Start the physics plugin.
const physics = new AmmoPhysics(scene)

// Add a physics body to a three.js mesh.

// Add a clock
const clock = new THREE.Clock()

// Update the physics in your animation loop
const animate = () => {
  physics.update(clock.getDelta() * 1000)
  renderer.render(scene, camera)


enable3d.io_examples_compare-physics-body-shapes.html(Pixel 2)

enable3d.io_examples_wrecking-ball-with-metal-chain.html(Pixel 2)

enable3d.io_examples_kinematic-body-orbiting-around-sun.html(Pixel 2)

enable3d.io_examples_first-phaser-game-3d-version.html(Pixel 2)

enable3d.io_examples_3rd-person-camera.html(Pixel 2)

Hope you :heart: it!


In the latest version (0.0.16), I added a headless mode. It allows you to use ammo.js on the server (node.js) without the need of packages like electron, puppeteer or jsdom. Only pure node.js.

It is also easily possible to load gltf (.glb) models and add whatever shape you want, like Hull, HACD or your custom compound shape.

Here are both examples:

You can, of course, also include three and create your meshes as you are used to:

// ...
const THREE = require('three')
// ...
const geometry = new THREE.BoxGeometry()
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 })
const box = new THREE.Mesh(geometry, material) = 'box' // give it a name
box.position.set(0, 5, 0) // set y to 5
this.physics.add.existing(box) // add physics to the box

// and then push it to the objects array

This give exactly the same result as:

const box ={ name: 'box', y: 5 })
1 Like

Looks nice!

I was just browsing through the examples, but it seems like there is something horribly wrong with the water demo.

I’m running a Core i7 8700K with an RTX2080 Ti, and my FPS seems to be sitting between 5 and 10 :exploding_head:

Not sure whats going on there.

edit: This one:

Thanks :slight_smile:

Yes, I know. There is already a solution, but I have not implemented it yet. Will fix this in the next version.

Ah I saw that topic before. Didn’t realize it was this specific issue. Cheers!

Awesome! Love the new standalone mode. I added it to the list of Three.js-friendly physics engines: Preferred physics engine (cannon.js, ammo.js, DIY...)


Thanks, glad you like it :slight_smile:

It is actually the “headless mode” that is used on node.js.

The “standalone mode” is a different thing, that does not much at the moment. But I will add more functionality to it in the future.

1 Like

I’m about to implement a WebWorker for ammo.js. Infact, in my testing, I managed to implement the WebAssembly version of ammo.js into a WebWorker.

Hope I can release it soon :slight_smile: