Matter.js Velocity Iterations and Projectile Accuracy
In Matter.js, the physics engine relies on iterative solver loops to calculate how forces, impulses, and constraints interact during collisions. Reducing the engine's velocity iterations lowers CPU load, but it significantly degrades the simulation accuracy of high-speed projectiles. This article examines how lowering this parameter leads to unrealistic rebound angles, erratic momentum conservation, increased clipping, and compromised ballistic trajectories.
The Role of Velocity Iterations
Matter.js uses a rigid-body physics pipeline where collision resolution occurs over two main phases: position iterations and velocity iterations. While position iterations correct body overlaps and penetration, velocity iterations resolve the impulses necessary to reflect restitution (bounciness) and friction.
By default, Matter.js sets engine.velocityIterations to
4. Each iteration refines the velocity vectors of colliding bodies until
an equilibrium is reached. Lowering this value means the impulse solver
halts its calculations early, accepting an approximation of linear and
angular velocity rather than a physically correct solution.
Inaccurate Momentum Transfer and Rebound Angles
High-speed projectiles deliver large amounts of kinetic energy over a fraction of a millisecond. When a fast projectile strikes a surface, the impulse required to push it back or halt it is extremely high.
With reduced velocity iterations:
- Energy Loss or Gain: The impulse solver cannot adequately resolve high-energy impacts, leading to scenarios where projectiles lose excessive kinetic energy (feeling "sluggish" or dead upon impact) or gain non-physical phantom velocity.
- Skewed Reflection Vectors: Projectiles hitting angled surfaces or corners will deflect at incorrect trajectories. The tangential forces (friction) and normal forces (restitution) fail to balance, corrupting the law of reflection.
Exacerbated Tunneling and Penetration
Matter.js uses discrete collision detection rather than continuous collision detection (CCD). Bodies jump from one discrete point to another based on their velocity vector and the delta time step.
When velocity iterations are reduced:
- Delayed Velocity Arrest: If a high-speed body collides with a thin wall, the solver needs strong impulse corrections to halt the forward velocity instantly. With fewer iterations, the remaining forward velocity persists into the next frame.
- Tunneling Compounding: While position iterations attempt to push the overlapping bodies apart, an under-resolved velocity will push the projectile deeper into or straight through the obstacle on the subsequent frame, causing total collision failure (tunneling).
Trajectory Drift and Multi-Body Inconsistencies
Reducing velocity iterations causes cumulative numerical errors when a projectile interacts with complex environments:
- Glancing Impacts: If a bullet or ball grazes a surface at high speed, reduced iterations often fail to register the minor tangential impulse correctly, causing the projectile to either stick to the surface or pass through undisturbed.
- Chained Collisions: If a projectile strikes multiple stacked or connected objects, resolving the velocity throughout the chain requires sufficient solver passes. Low iterations will cause only the first contact point to receive impulse, leaving secondary bodies static and causing the projectile to compress unnaturally against the target.
Balancing Performance and Accuracy
Reducing velocity iterations is a standard optimization technique for
low-end hardware or scenes with hundreds of slow-moving entities.
However, applying this reduction in scenes involving high-speed
projectiles creates noticeable physics anomalies. To preserve ballistic
accuracy without overburdening the CPU, developers should keep velocity
iterations at or above default levels and instead optimize high-speed
interactions by reducing the engine time step
(engine.timing.delta), using sub-stepping, or implementing
raycast-based collision checks for projectile paths.