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.92k stars 7.08k forks source link

Dark edge when drawing to RenderTexture that has mask applied to it #5809

Open ccaleb opened 3 years ago

ccaleb commented 3 years ago

Version

Description

I have a brush texture that I am applying to a RenderTexture when the user clicks and moves their mouse over it. The brush texture is circular in shape with a dithered alpha edge around the outside. This gives the brush a soft edge that looks quite nice when the user draws onto the render texture with it.

This works as expected. However, I also need to apply a mask to the render texture so that the user’s brush strokes do not appear on certain areas of the render texture. Additionally, the mask also has dithered alpha edges around its edge so that the user’s paint strokes fade out as they near the outside area of the render texture.

However, when I apply my mask to the render texture, the soft edge around the paint brush texture suddenly exhibit a harsh darkened edge rather than the nice soft edge that I was previously seeing. When I remove the mask, the brush texture once again shows the soft edges that I was expecting.

For the avoidance of doubt, I am referring to brush strokes that should still be perfectly visible on screen, rather than brush strokes that might now be hidden from view due to the mask being applied.

Here’s a rough outline of the steps I’m carrying out:

  1. Load a brush and mask texture
  2. Create a RenderTexture
  3. Create a Bitmap mask using the mask texture and apply it to the RenderTexture
  4. Listen for mouse down, move, and up events to track when user is drawing on the RenderTexture
  5. When pointer is down or moving, then use RenderTexture::draw() to draw the brush texture onto the RenderTexture and also tint it red

Expected Behaviour

When drawing to the RenderTexture I would expect the brush to look identical no matter whether a mask was applied or not.

Actual Behaviour

The first image shows the brush being applied to the RenderTexture when it has no mask applied. Notice the nice soft edges around the brush strokes.

No mask applied

The second image has the mask applied and now shows a darkened edge around the brush strokes. The two white ovals in the second image are intended and are created by the mask.

Mask applied

Example Test Code

A CodePen example can be found here.

There is a constant named useMask at the top of the JavaScript. It’s initially set to false.

You can see the main parts of the code below.

const useMask = false;

createRenderTexture ()
{
  const rt = this.add.renderTexture(0, 0, w, h);
  rt.setOrigin(0.5, 0.5);
  rt.clear();
  rt.x = x;
  rt.y = y;
  if (useMask) rt.mask = this.createMask();

  rt.setInteractive().on('pointerdown', this.pointerDown, this);
  rt.setInteractive().on('pointermove', this.pointerMove, this);
  rt.setInteractive().on('pointerup', this.pointerUp, this);

  this.renderTexture = rt;
}

createMask ()
{
  const mask = this.add.image(x, y, 'mask');
  mask.setScale(0.5);
  this.children.remove(mask);

  return new Phaser.Display.Masks.BitmapMask(this, mask);
}

pointerMove (pointer, localX, localY, event)
{
  if (this.drawing) this.drawBrushAt(localX, localY);
}

drawBrushAt (x, y, color)
{
  this.renderTexture.draw('brush', x - 32, y - 32, 1, red);
}

If you run the code you will initially be able to draw to the RenderTexture but without the mask applied. Set useMask to true then re-run the demo. You should notice when you draw that your lines now have a darkened edge rather than the previous softer edge.

Example Test Code

The brush texture I am using can be found here. The mask texture I am using can be found here.

EddieCameron commented 2 years ago

I'm seeing this too, without a render texture, just a masked sprite

Screen Shot 2021-10-13 at 16 29 01