Blog>
Snippets

Physics in Three.js Using Cannon.js

Integrate Cannon.js physics engine with Three.js to add realistic physics to the objects in the scene, including gravity and collisions.
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// Set up the world for Cannon.js
const world = new CANNON.World();
world.gravity.set(0, -9.82, 0); // Earth's gravity in m/s²

// Create a sphere body with Cannon.js
const radius = 1;
const sphereShape = new CANNON.Sphere(radius);
const sphereBody = new CANNON.Body({
    mass: 5, // kg
    shape: sphereShape
});
sphereBody.position.set(0, 10, 0); // Position the body at an elevated position
camera.position.z = 5;
Initial setup of the Three.js scene, camera, and renderer. This also includes the initial configuration of the Cannon.js world, setting the gravity, and creating a spherical physics body with a specific mass and shape.
const geometry = new THREE.SphereGeometry(radius, 32, 32);
const material = new THREE.MeshBasicMaterial({ color: 0xffff00 });
const sphere = new THREE.Mesh(geometry, material);

scene.add(sphere);
world.add(sphereBody);

// Sync the position of the Three.js mesh with the Cannon.js body
function updatePhysics() {
    world.step(1 / 60);
    sphere.position.copy(sphereBody.position);
    sphere.quaternion.copy(sphereBody.quaternion);
}
Creates a Three.js sphere mesh, adds it to the scene, and adds the Cannon.js sphere body to the physics world. A function to update the physics is defined, syncing the positions and rotations of the Three.js mesh with the Cannon.js body each frame.
// Create a plane geometry for the ground
const planeGeometry = new THREE.PlaneGeometry(10, 10);
const planeMaterial = new THREE.MeshBasicMaterial({ color: 0x777777, side: THREE.DoubleSide });
const plane = new THREE.Mesh(planeGeometry, planeMaterial);
plane.rotation.x = -Math.PI / 2;
scene.add(plane);

// Create ground body for Cannon.js
const groundShape = new CANNON.Plane();
const groundBody = new CANNON.Body({ mass: 0 }); // Setting mass to 0 makes it static
groundBody.addShape(groundShape);
world.addBody(groundBody);
Creates a Three.js plane mesh to represent the ground, and a corresponding static Cannon.js ground body. The ground body is added to the world with zero mass, indicating that it is immovable.
function animate() {
    requestAnimationFrame(animate);
    updatePhysics();
    renderer.render(scene, camera);
}

animate();
Defines the animate function, which is the rendering loop. It continuously updates the physics and renders the scene. This is where the Three.js mesh and Cannon.js body stay in sync.