Matter.js SAT Performance with High Vertex Counts
Using rigid bodies with high vertex counts in Matter.js significantly degrades physics simulation performance, primarily due to the mathematical overhead of the Separating Axis Theorem (SAT) during collision detection. In Matter.js, SAT serves as the core narrowphase algorithm to determine whether two convex shapes overlap and to calculate collision vectors. When vertex density increases, the calculations required per frame multiply quadratically, causing CPU bottlenecks, garbage collection pressure, and noticeable drops in framerate.
The Mathematical Cost of SAT Projection
The Separating Axis Theorem dictates that two convex bodies do not collide if an axis exists along which their projections do not overlap. To evaluate this:
- Axis Generation: The algorithm generates potential separating axes, which correspond to the perpendicular normal vectors of every edge on both polygons. A body with \(N\) vertices produces \(N\) potential axes. For two interacting bodies with \(N\) and \(M\) vertices, the engine must evaluate up to \(N + M\) axes.
- Vertex Projection: On each tested axis, every single vertex from both bodies must be projected via vector dot products to find the minimum and maximum extents of the shapes.
Because every axis requires projecting all vertices of both shapes, testing collision between two bodies scales at approximately \(\mathcal{O}((N + M) \times (N + M))\) operations in the worst-case scenario where bodies overlap or are in close proximity. As vertex counts escalate from basic shapes (4–8 vertices) to complex silhouettes (50–100+ vertices), the number of dot products executed in a single frame increases by orders of magnitude.
Narrowphase Bottlenecks in Matter.js
Matter.js uses a broadphase step (bounding box trees or spatial
hashing) to quickly discard bodies that are nowhere near each other.
However, once bounding boxes intersect, the engine must invoke
Matter.SAT.collides.
When high-vertex bodies are closely grouped, stacked, or resting:
- Early Exits Fail: While SAT can exit early the moment a separating axis is identified, intersecting or deeply contacting bodies require checking nearly every axis before confirming collision and determining the Minimum Translation Vector (MTV).
- Contact Point Generation: In addition to verifying overlap, Matter.js must calculate contact manifolds and support points for solver iterations, an operation that grows increasingly expensive with dense vertex arrays.
Compounding Effects of Non-Convex Decomposition
Matter.js only supports convex polygons for SAT. If a concave body
with a high vertex count is imported, it must be decomposed into a set
of convex sub-bodies (typically using tools like
poly-decomp).
A single complex concave shape can easily split into dozens of convex parts. In this scenario, the total collision cost multiplies exponentially: every sub-part of body A must run SAT against every overlapping sub-part of body B. This turns what appears to be a single collision check into dozens of high-vertex polygon evaluations per frame.
CPU and Memory Pressure
In browser environments, Matter.js runs on a single JavaScript thread. Heavy SAT operations directly contend with application logic and rendering routines. The excessive vector allocations and mathematical operations within the SAT loop create:
- Thermal Throttling: Sustained mathematical execution causes mobile devices to throttle performance quickly.
- Garbage Collection Spikes: Frequent vector creation and math manipulation in tight loops can increase memory churn, leading to sporadic garbage collection pauses and physics stutter.
Optimization Strategies
To maintain stable 60 FPS simulations while working with complex shapes in Matter.js:
- Vertex Decimation: Pre-process custom polygon paths using simplification algorithms (such as Ramer-Douglas-Peucker) to reduce vertices to the functional minimum required for visual fidelity.
- Compound Primitive Colliders: Approximate complex silhouettes using combinations of simple geometric primitives (rectangles and circles). Circles are especially efficient because SAT evaluates circle-polygon collisions with fewer axes.
- Broadphase and Category Filtering: Strictly tune
collision masks, categories, and sleep thresholds
(
body.isSleeping) to prevent high-vertex resting bodies from triggering unnecessary narrowphase SAT passes.