phaserjs / phaserjs/phaser

Drawing a container/gameobject with a mask to a DynamicTexture/RenderTexture doesn't account for mask position so the drawn result is wrong

Open
#7,000 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
JavaScript
Stars
40.3k
Forks
7.2k
PR merge metrics
No merged PRs in 30d

Description

Version

  • Phaser Version: 3.86.0
  • Operating system: Windows/Mac/iOS/Android
  • Browser: Chrome/Safari

Description

With Phaser 3.60+, when drawing to a dynamic/rendertexture, it now respects any masks that the gameobject being drawn has. See the release notes here. This works and is a great feature, except if you want to draw the object at a different position than it currently is and use the optional 2nd/3rd parameter to move/set the position of the object being drawn. The mask doesn't get moved, so the end result is wrong.

Example Test Code

import Phaser from 'phaser';

export default class MaskDrawingIssue extends Phaser.Scene {
  create() {
    // create an object to mask with
    this.maskObject = this.add.circle(this.scale.width / 2, this.scale.height / 2, 100, 0xff0000).setVisible(false);

    // create an object to mask
    this.objectToMask = this.add.rectangle(this.scale.width / 2, this.scale.height / 2, 400,100,0x00ff00);
    this.objectToMask.setMask(this.add.bitmapMask(this.maskObject));

    // create a DT
    this.dt = this.textures.addDynamicTexture('test1', this.objectToMask.width * 2, this.objectToMask.height * 2);

    // fill the area to make it easier to see
    this.dt.fill(0xffffff);

    // draw the object at a specific spot in the DT (at the center in this case)
    this.dt.draw(this.objectToMask, this.objectToMask.width,this.objectToMask.height);

    // show it
    this.showDt = this.add.image(0,0,'test1').setOrigin(0);

    // do the same with an RT
    this.rt = this.add.renderTexture(0,this.scale.height - this.objectToMask.height * 2, this.objectToMask.width * 2, this.objectToMask.height * 2).setOrigin(0);
    this.rt.fill(0xffffff);
    this.rt.draw(this.objectToMask, this.objectToMask.width,this.objectToMask.height);

    // the following code will draw the object with a mask correctly
    // this.rt = this.add.renderTexture(0,0, this.scale.width, this.scale.height).setOrigin(0);
    // this.rt.fill(0xffffff);
    // this.rt.draw(this.objectToMask);

    // workaround to get the object to draw (but without the mask)
    // this.rt = this.add.renderTexture(0,0, this.objectToMask.width * 2, this.objectToMask.height * 2).setOrigin(0);
    // this.rt.fill(0xffffff);
    // const mask = this.objectToMask.mask;
    // this.objectToMask.clearMask();
    // this.rt.draw(this.objectToMask, this.objectToMask.width,this.objectToMask.height);
    // this.objectToMask.setMask(mask);
  }
}

Additional Information

I'm not sure what the intent is, but I feel like if you want to pass in an x/y value into the draw call, it should adjust the mask accordingly. Alternatively, it might make sense to add a 4th parameter to the draw function (and other relevant functions) to ignore masks.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the provided reproduction and the Phaser 3.60 DynamicTextures release notes, then trace the DynamicTexture and RenderTexture draw calls when an object has a mask and an x/y position is supplied. Compare that behavior with drawing at the object's current position and determine which documented behavior should be preserved. Done means the example renders the masked object correctly at the requested position, with coverage for the chosen behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
computer-graphics, game-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.