Matter.js Detector Collision Filtering Explained

In Matter.js, performance is optimized during the broad-phase collision detection stage by skipping costly geometric calculations between bodies that are configured not to interact. The Matter.Detector module achieves this through the internal canCollide(filterA, filterB) method, which evaluates each rigid body's collisionFilter object. This article breaks down the exact criteria—namely collision groups, category bitfields, and mask bitfields—that Matter.Detector uses to skip collision checks between incompatible bodies.

The Priority Rule: Collision Groups

Before evaluating categories or masks, Matter.Detector checks the group property (filter.group). Collision groups override standard category and mask behavior:

The Category and Mask Bitwise Criteria

When group rules do not apply, Matter.Detector determines collision compatibility using bitwise operations between each body's category and mask properties.

By default, every body in Matter.js has:

For two bodies, Body A and Body B, to be eligible for collision detection, the following boolean condition must evaluate to true:

(filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0

Why Collision Checks Are Skipped

Matter.Detector will immediately discard the pair and skip narrow-phase collision calculations if either of the following conditions is met:

  1. Body A does not listen to Body B: The bitwise AND between Body A's mask and Body B's category results in 0 ((filterA.mask & filterB.category) === 0).
  2. Body B does not listen to Body A: The bitwise AND between Body B's mask and Body A's category results in 0 ((filterB.mask & filterA.category) === 0).

Because the check requires two-way consent via the logical AND (&&), compatibility must be mutual. If even one body's mask excludes the other body's category bit, Matter.Detector eliminates the pair from the collision pipeline.