Why Friction Is Costly in Physics Engines Like Matter.js

Simulating realistic friction in rigid body physics engines like Matter.js requires significantly more computational power than simulating basic motion or gravity. While standard motion relies on basic linear equations of velocity and acceleration, friction involves non-linear constraints, inter-body dependencies, and iterative mathematical solvers. This article explores the mathematical and architectural reasons why friction resolution remains one of the heaviest bottlenecks in real-time 2D and 3D physics simulation.

The Non-Linear Nature of Coulomb Friction

Unlike gravity, which applies a constant unidirectional acceleration, friction is governed by non-linear behavioral models, most commonly the Coulomb friction model. Coulomb friction introduces two distinct operational modes:

  1. Static Friction: Opposes any tangential force up to a threshold (\(F_s \le \mu_s F_n\)) to keep objects stationary relative to each other.
  2. Dynamic (Kinetic) Friction: Opposes relative tangential velocity with a constant resistive force proportional to the normal load (\(F_k = \mu_k F_n\)) once the static threshold is breached.

This bifurcation means an engine cannot use a single linear equation to calculate friction forces. The solver must continuously evaluate whether a contact point is sticking or sliding, altering the equation system dynamically depending on the outcome.

Tangential and Normal Force Coupling

Friction cannot be resolved independently from normal collision forces. The maximum allowable frictional impulse depends directly on the magnitude of the normal impulse holding the two surfaces apart.

Because collision resolution is inherently coupled:

This circular dependency prevents the engine from solving contact forces in a single pass.

Iterative Constraint Solvers

Engines like Matter.js and Box2D use iterative impulse-based solvers (such as Sequential Impulses or Projected Gauss-Seidel) to handle rigid body constraints. Rather than solving a massive, computationally prohibitive matrix system via direct methods (like Linear Complementarity Problem solvers) in every frame, the engine loops through constraints multiple times to approximate an equilibrium.

For every contact point:

  1. The solver resolves the normal impulse.
  2. The solver projects and clamps the tangential impulse based on the current friction coefficient and normal force.
  3. The solver applies equal and opposite changes in momentum to both participating bodies.

To achieve stability—especially in scenes with resting contacts or stacks of bodies—Matter.js must execute this loop multiple times per frame (controlled by the engine's iteration settings). As the number of contact pairs grows, the number of required mathematical operations scales rapidly.

Contact Manifolds and Multi-Body Stacking

In complex scenes, such as a box resting on an inclined plane or a tall stack of objects, single objects generate multiple contact points (contact manifolds). Friction forces propagate through these manifolds from object to object.

If friction is under-resolved due to low iteration counts, objects exhibit unnatural "creeping," jitter, or sudden energy explosions. Maintaining realistic rest states requires deep convergence across the entire system, multiplying the number of mathematical operations across all active contact pairs.

JavaScript Runtime Constraints in Matter.js

Beyond algorithmic complexity, Matter.js operates inside the browser's JavaScript runtime environment. Unlike native physics engines written in C++ or Rust that leverage single instruction, multiple data (SIMD) vector instructions and manual memory layouts, JavaScript engines introduce additional overhead:

Friction represents the convergence of complex non-linear physics, tightly coupled constraint mathematics, and high-frequency numerical approximations, making it one of the most resource-intensive aspects of rigid body simulation.