Drawing a container/gameobject with a mask to a DynamicTexture/RenderTexture doesn't account for mask position so the drawn result is wrong
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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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