How to Fix Jittering Objects in Matter.js
In Matter.js, resting physics bodies often suffer from micro-vibrations or jittering caused by continuous collision-resolution calculations and rounding errors. This article outlines the most effective techniques to eliminate resting jitter, covering how to activate the built-in sleeping mechanic, tune solver iterations, optimize surface friction and restitution, and clamp micro-velocities directly in the engine update cycle.
1. Enable the Sleeping Mechanic
The most common cause of jitter is that Matter.js continues to recalculate collisions and apply micro-forces to stationary objects every frame. Enabling the sleeping system allows the engine to freeze bodies that have settled below a specific motion threshold until another body collides with them.
Set enableSleeping to true on the engine
instance:
const engine = Matter.Engine.create({
enableSleeping: true
});You can also configure sleep thresholds on individual bodies using
sleepThreshold:
const box = Matter.Bodies.rectangle(x, y, width, height, {
sleepThreshold: 15 // Number of frames below motion threshold before sleeping
});2. Increase Solver Iterations
When objects stack or rest on one another, the default collision resolution iterations may not fully stabilize before the next frame renders. Increasing the engine's velocity and position iterations gives the solver more passes to resolve overlaps cleanly.
engine.positionIterations = 10; // Default is 6
engine.velocityIterations = 8; // Default is 4Higher iteration counts increase stability at the cost of slightly higher CPU usage.
3. Remove Restitution (Bounciness)
A non-zero restitution property causes bodies to continually bounce imperceptibly when resting against static ground or other objects. Ensure that both the resting object and the floor have restitution explicitly set to zero:
const floor = Matter.Bodies.rectangle(x, y, width, height, {
isStatic: true,
restitution: 0
});
const restingBody = Matter.Bodies.rectangle(x, y, width, height, {
restitution: 0
});4. Optimize Static and Dynamic Friction
Sudden transitions between kinetic and static friction can produce a "chatter" or stuttering effect. Setting adequate static friction and standard friction ensures resting bodies lock into place without sliding back and forth microscopically:
const stableBody = Matter.Bodies.rectangle(x, y, width, height, {
friction: 0.1,
frictionStatic: 0.5,
frictionAir: 0.01
});5. Manually Clamp Micro-Velocities
If you cannot use enableSleeping due to gameplay
requirements, you can clamp tiny residual velocities directly inside the
beforeUpdate event listener. This eliminates floating-point
drift that causes visual shaking:
Matter.Events.on(engine, 'beforeUpdate', () => {
const threshold = 0.05;
compositeBodies.forEach((body) => {
if (!body.isStatic) {
if (Math.abs(body.velocity.x) < threshold) {
Matter.Body.setVelocity(body, { x: 0, y: body.velocity.y });
}
if (Math.abs(body.velocity.y) < threshold) {
Matter.Body.setVelocity(body, { x: body.velocity.x, y: 0 });
}
if (Math.abs(body.angularVelocity) < threshold) {
Matter.Body.setAngularVelocity(body, 0);
}
}
});
});6. Avoid Disproportionate Mass Ratios
Stressing the physics solver by placing extremely heavy objects on top of light objects frequently causes visible jittering. Keep mass ratios between stacked interacting bodies within a balanced range (ideally under a 1:10 ratio) to maintain numeric stability during contact resolution.