phaserjs / phaser

Phaser is a fun, free and fast 2D game framework for making HTML5 games for desktop and mobile web browsers, supporting Canvas and WebGL rendering.
https://phaser.io
MIT License
36.95k stars 7.08k forks source link

Low fps on mobile with any mask #5360

Closed wingcd closed 3 years ago

wingcd commented 3 years ago

Version

Description

On mobile in WebGL type, if there has masks on gameobjects, then scene running scends, the fps will be too lower. And the ui lags very much.

Example Test 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<20;i++) {
        let img = this.add.image(i*10, i*10, 'aaa');
        let g = this.make.graphics({x: i*10 + 100, y: i*10 + 100});
        g.fillCircle(0, 0, 50);
        img.setMask(g.createGeometryMask());
    }
}

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

    if(!this.__fps) {
        this.__fps = this.add.text(0,0,"",{
            color: "#ff0000"
        });
    }
    this.__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); }

Additional Information

photonstorm commented 3 years ago

Masks can and should be, shared across Game Objects. One single mask should be used for as many Game Objects as possible, otherwise, you cause lots of un-needed WebGL ops every frame, which would result in lag on low-end mobiles. This same example can be done with a single mask and 20 images. Geometry masks are also much more expensive than Bitmap Masks due to the way in which they use the stencil buffer.

This issue isn't something that can be 'fixed'. Masks are already batched and shared between objects to avoid unnecessary calls, there's nothing more that can really be done with them other than you being careful with their construction. Follow-up in Discord or the Forum for further ideas.

wingcd commented 3 years ago

Hi, how can i share the mask in different position gameobject. I shared the mask just the last gameobject display correctly. Thanks.

jbromberg commented 1 year ago

Following up here: it appears bitmap masks are tied to the location of a game object. How then are we supposed to share them across objects at different positions?

photonstorm commented 1 year ago

Following up here: it appears bitmap masks are tied to the location of a game object. How then are we supposed to share them across objects at different positions?

There's no point commenting on a 2-year-old issue. Please open it as a discussion or ask on Discord.