Share mask for GameObjects

Hi, i just know one mask for gameobject, but those way with low fps on mobile device.So how can i do for sharing the mask to gameobject with different position.
That’s the sample code:

    class UIScene extends Phaser.Scene {

    constructor() {
        super({key: 'game', active: true})
    }

    preload() {

        this.load.image('aaa', './res/1.jpg');
    }

    create() {       
        for(let i=0;i<10;i++) {
            let img = this.add.image(i*10+100, i*10+100, 'aaa');
            let g = this.add.graphics({x: img.x, y: img.y});
            g.visible = false;           
            g.fillStyle(0x1, 1);
            img.mask = g.createGeometryMask(g.fillCircle(0, 0, 50));
        }
    }

    update(time: number, delta: number) {
        super.update(time, delta);

        if(!(this as any).__fps) {
            (this as any).__fps = this.add.text(0,0,"",{
                color: "#00ff00"
            });
        }
        (this as any).__fps.text = 1000 / delta;
     }
 }

 export class App extends Phaser.Game {
    constructor(config: Phaser.Types.Core.GameConfig) {
        super(config);
    }
}

const config: Phaser.Types.Core.GameConfig = {
    title: "Starfall",
    parent: "game",
    type: Phaser.WEBGL,
    width: 960,
    height: 540,
    backgroundColor: "#f0f0f0",    
    scene: [UIScene], 
    scale: {
        mode: Phaser.Scale.RESIZE,
        autoCenter: Phaser.Scale.CENTER_BOTH,
        autoRound: true,   
    },
};

window.onload = () => {
    var game = new App(config);
}

Phaser version is 3.24.1

:wave:

For that you might try using a RenderTexture or CanvasTexture instead. Or edit the original image, if possible.

But it’s not possible to use a single mask in multiple positions.

Thanks.
I think so. but phaser author said can just use one mask.
So i am confused about that.

You can draw multiple shapes on one mask, though:

let g = this.add.graphics();
let mask = g.createGeometryMask();

g.visible = false;

for (let i = 0; i < 10; i++) {
  let img = this.add.image(i * 10 + 100, i * 10 + 100, 'aaa');
  img.setMask(mask);
  g.fillStyle(0x1, 1);
  g.fillCircle(img.x, img.y, 50);
}

Nope, this way show wrong effect.
share mask:

masks:

Then you’re back to RenderTexture, CanvasTexture, or your image editor.

There’s no way one mask can do what you want.

Ok,thanks.

Add all the images to a container object, and then apply 1 mask to that container.

The way you posted caused performance issues for us.

To clarify, when I said that multiple Game Objects can use a single mask, it only works if those Game Objects do not overlap. Masks are rendered in world space, not local space, so you can draw multiple shapes to a single mask and each shape can be at the position of a Game Object.

Internally the mask is cached, so if, for example, 20 Game Objects all use the same mask, no extra processing happens as the mask is only set-up and torn-down once (as long as those Game Objects are consecutively ordered in the render list)

Geometry Masks use the stencil buffer in WebGL, or Canvas Path API, so the more complex the shape (especially circles and arcs), the bigger the stencil buffer becomes and it just all takes a lot more processing power. Bitmap Masks use a custom shader, so are faster, but still require flushing the WebGL batch first.

If you need to use them in large volumes, you should look at generating textures instead, rather than using an actual mask at run-time.