Masks - samme/phaser3-faq GitHub Wiki

A mask is created from a game object source (which is usually invisible) and occludes one or more targets (game objects or cameras).

There are two kinds of masks.

Bitmap mask

A bunny masked by a ring

A bitmap mask is created from any textured game object (e.g., Image, Blitter, Particle Emitter). The target alpha is multiplied by the source alpha at each pixel:

source alpha * target alpha = rendered alpha

If the mask is inverted, the target alpha is multiplied by the complement of the source alpha:

(1 - source alpha) * target alpha = rendered alpha

The source pixel color doesn't matter.

Geometry mask

A sci-fi scene masked by a Pacman shape

A geometry mask is created from a Graphics game object. The target is visible in filled regions of the source. The fill color doesn't matter. If the mask is inverted, the target is visible in unfilled regions of the source.

Creating masks

You create a mask from a game object source. There a few ways to do it but the clearest are

const image = this.add.image(/*…*/);
const mask = image.createBitmapMask();
const graphics = this.add.graphics(/*…*/);
const mask = graphics.createGeometryMask();

You can invert the mask:

mask.invertAlpha = true;

That's all you'll do with the mask itself. It's a rendering construct only.

Typically you don't want to show the mask source directly. You can either hide it or keep it off the display list:

const image = this.add.image(/*…*/).setVisible(false);
// OR
const image = this.make.image({/*…*/}, false);

But for debugging you may want to keep the mask source partly visible:

const image = this.add.image(/*…*/).setAlpha(0.5);

With a geometry mask any filled shapes in the graphic reveal the mask targets. The fill color doesn't matter, so I usually use 0 (black). As with any graphics, you can fill as many shapes as you need.

graphics.fillStyle(0).fillCircle(0, 0, 100).fillCircle(25, 25, 50);

A mask source mustn't be in a Container. (It will still work, but in the wrong position.)

You move, rotate, or scale the mask source, not the mask object itself. For bitmap masks, you can also change the source alpha.

Assign the mask to a target, which is a camera or game object. For cameras the mask will work in the camera's viewport space unless you pass fixedPosition = false.

// add:
this.cameras.main.setMask(mask, false);
// remove:
this.cameras.main.clearMask(mask);
// add:
layer.setMask(mask);
// remove:
layer.clearMask();

There's no way to disable a mask directly; you have to clear it from every target.

Several game objects (targets) can use the same mask, but one game object can use only one mask. The mask always acts in global space. It's not a local effect like a crop rectangle.