Physics in Spark AR

ashley fletcher
Jul 5, 2019 · 5 min read

How to use Cannon.js physics in Spark AR

Image for post
Image for post

I’ve recently been playing with physics in Spark AR, and I thought I would share the journey so far. I’ve also made a project and an npm package that might help kickstart your physics exploration.

This is by no means a complete guide to physics engines, but it should be enough to get you started. For my experiments so far, I’ve been using Cannon.js.

The concept

The way I think about physics engines, is that there’s a visual world and a physics world. Rendering a simulation is all about keeping the two worlds in sync.

The physics engine keeps track of the object positions based on forces. To keep these two worlds in sync, we need to bind the positions of everything in the two worlds together. You don’t have to explicitly say where a scene object should move or how it should behave, the physics engine handles all of that for us!

Getting started

To help you along with the daunting task of integrating a physics engine, I’ve started an npm package to help with the binding of the Spark world and the Cannon physics world.

How to use

The easiest way to get started will be to use the template within the example folder on the repository.

Run this command in the terminal at the directory of the example project. It will install all the dependencies.

npm i

Now you have all the dependencies run

npm run build

This should build a new script.js file in the physicsTest project.

Open up the physicsTest project, and you should see boxes and spheres falling down.

Image for post
Image for post

The main source file is the index.js in the src folder of the example. Look in there to see how I use the npm package for binding objects together.

The module

The module has helpers for keeping together the movement in the Cannon world and the Spark world. It does this by taking something I’ve called World Objects. World Objects contain a scene object and a physics body. Keeping the two parts together makes updating and syncing positions way more straightforward.

When we have our World Objects created, we pass them to the constructor, which sets up the Cannon world and adds our objects. It also exposes the original Cannon class so that it can be used as standard.

On every loop, you call update. It iterates over all the World Objects and updates the scene object’s position and rotation based on its physics object. It also steps the physics world forward by a delta time to get the new positions for all the objects.


Spark seems to have no sense of a global variable/scope. However, in the Cannon module, it assigns a value to a ‘performance’ variable, that doesn’t seem to get explicitly declared. To fix this, in the Cannon module, I added the variable ‘performance’ into the source at /src/world/World.js on line 501. That is why the package has a local version of the cannon library that isn’t from npm.

Another pitfall is that the ground plane will be on the wrong axis at the start. That’s where this line comes in to flip it back 90 degrees to where it should be.

groundBody.quaternion.setFromAxisAngle(new CANNON.Vec3(1, 0, 0), -Math.PI / 2)

Here’s one I made earlier

The first effect I made with the physics engine was a bowling simulation on Instagram which you can try here:

Image for post
Image for post

Here’s the repository for that project:

This project shows a slightly more practical approach to how you might apply physics to an effect, rather than just having objects falling to the ground. It also shows how to use the original cannon object in combination with the module.

Without too much extra code, we can start to interact with the objects by applying impulses to the physics objects.

What I’ve learned

The reactive programming in Spark AR clashes with the more traditional style of Cannon.js, which causes quite a bit of a performance hit. An example of this has no frame update loop to plug into. My approach was to just use an interval for the update loop. This type of approach causes a lot of warnings that popup for using too many callbacks. So this is worth noting when starting your own physics-based effects.

Depending on your use case, you might get away with using physics in production. However, it might be too intensive on resources in Spark AR to get something more advanced.


This is only the beginning of the physics integration. There’s lots more to do so if you have anything to add just open a pull request or issue on GitHub.

Syncing positions from Spark to Cannon is still missing in the module. I ran into a lot of issues getting positions of objects as values, so any help on this would be appreciated! This is where the reactive programming becomes the biggest challenge.

Start Creating!

Over the next couple of weeks, I’ll start documenting the module and include any contributions made. So keep an eye out for improvements and progress updates.

If you want any more info on physics just drop me a message on Instagram: alt.reality

For more information about Byte’s use of AR, visit our website
And for any questions contact


We are a marketing technology agency.

ashley fletcher

Written by

Developer at Byte working on Augmented Reality and Creative Tech



We are a marketing technology agency. We combine technology and creativity to solve brands’ problems.

ashley fletcher

Written by

Developer at Byte working on Augmented Reality and Creative Tech



We are a marketing technology agency. We combine technology and creativity to solve brands’ problems.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store