Ammo.js Sub-step Count CPU Performance Impact

This article examines how drastically increasing the sub-step count in the ammo.js physics engine affects CPU performance. It explains the relationship between sub-stepping and CPU load, details why simulation complexity multiplies with higher step counts, and offers practical alternatives for maintaining physics stability without degrading application performance.

Understanding Sub-stepping in Ammo.js

Ammo.js, a direct JavaScript port of the Bullet Physics engine, updates its simulation using the stepSimulation method. This method takes three primary parameters: the elapsed time, the maximum number of sub-steps, and the fixed time step size.

When the elapsed time of a frame exceeds the fixed time step (typically 1/60th of a second), ammo.js divides the frame into multiple “sub-steps” to maintain mathematical stability. Drastically increasing the maximum sub-step count allows the engine to run more mini-simulations per frame, preventing fast-moving objects from passing through barriers (tunneling) and keeping complex constraint systems stable.

The Direct Impact on CPU Load

Increasing the sub-step count has a direct, often linear-to-exponential, negative impact on CPU performance. Each additional sub-step forces the CPU to execute the entire physics pipeline repeatedly within a single frame. This pipeline consists of several computationally heavy stages:

When the sub-step count is drastically increased, the CPU time spent on these four stages multiplies. If the CPU cannot complete these calculations within the budget of a single frame (e.g., 16.6ms for 60 FPS), it causes a performance drop, resulting in stuttering, frame rate drops, and unresponsive user interfaces.

The “Spiral of Death”

A critical risk of high sub-step configurations in WebGL and browser environments is the “spiral of death.”

If a complex physics frame takes too long to compute, the next frame’s elapsed time (timeStep) will be larger. To compensate for this larger elapsed time, ammo.js attempts to run even more sub-steps in the subsequent frame. This further increases the CPU load, causing the next frame to take even longer. This feedback loop quickly drags the frame rate down to single digits and can freeze the browser tab entirely.

Alternatives to High Sub-step Counts

Instead of drastically increasing sub-steps to solve physics instabilities, developers can use more CPU-efficient techniques:

  1. Continuous Collision Detection (CCD): For fast-moving objects, enable CCD on the specific rigid bodies. This projects a swept sphere to detect collisions before they happen, avoiding the need to increase sub-steps for the entire scene.
  2. Optimized Fixed Time Step: Instead of increasing the sub-step count, reduce the fixedTimeStep size (e.g., from 1/60 to 1/120) only when high precision is required, while keeping the maximum sub-step limit strictly capped.
  3. Rigid Body Deactivation: Ensure that objects that are not moving are properly put to “sleep” (deactivated). Ammo.js will skip collision detection and integration for deactivated bodies, freeing up CPU cycles for the active sub-steps.