Jump to content

Mask causing parent to be transparent


jere
 Share

Recommended Posts

Hi! I've been working on a canvas game for a while, hit some performance issues I just can't get around, and am hoping Pixi is the answer. So I'm struggling a bit to learn how to implement everything I can do in canvas in Pixi. So here goes my current problem:

I need a "source-atop" replacement. I want to draw some tile, overlay it with a totally opaque red sprite (eventually it'll be transparent, but it's opaque for this proof of concept), and then mask that sprite with the original tile objects which together will form an irregular shape. I wrote some test code and had no issues, but when I bring it into my project I get a very odd behavior: the second sprite suddenly appears transparent.

Here's the code:


		this.container = new PIXI.Container();
		this.container.position.x = this.i * tileSize;

		//base sprite
		var tileTexture = new PIXI.Texture(ssTexture, new PIXI.Rectangle(ssl[0], ssl[1], 16, 16));
		var tileSprite = new PIXI.Sprite(tileTexture);
		this.container.addChild(tileSprite);

		//tile mask generated from sprite
		var tileMask = new PIXI.Sprite(this.container.generateTexture(WebGLRenderer));

		//sunlight
		var sunlightOverlay = new PIXI.Sprite(sunlightTexture);
		this.container.addChild(sunlightOverlay);

		//mask sunlight
		sunlightOverlay.mask = tileMask;
		sunlightOverlay.addChild(tileMask);

		this.level.PixiContainer.children[this.j*2+1].addChild(this.container);

And here's the behavior:

1) Draw just the tile.

Pivmvbg.png

2) Draw the overlay. Obviously, it will have a different shape than the first tile which is why I need to mask it.

zTAr3cF.png

3) This is the object that will be used as a mask for the overlay. I used generateTexture() before adding the overlay.

DehBb5F.png

4) Now I set the mask to actually be used as a mask. I'm expecting a simple red square. It masks properly, but the overlay is inexplicably made transparent.

iTnvEC4.png

I don't know what to try here. There must be something simple I'm misunderstanding. Any thoughts?

Link to comment
Share on other sites

I am making an overhead game which features beams of sunlight*. A tile can be bathed in sunlight, which I plan to implement as a semi-transparent yellowish rectangle. If I don't mask the rectangle, it's going to have the shape of a rectangle instead of whatever else it's supposed to be covering. You can see the intended behavior here:

https://pbs.twimg.com/media/CU6bT3VWcAAa-Fn.png:large

The tile on the left with the torch is covered in sunlight. So is the character. A big block of yellow wouldn't work.

This seems like a perfect fit for masking. I don't follow you when you say "masking can solve problem only temporary."

 

*Sunlight isn't the only thing I need either. I need the same behavior for characters standing in the shadows and other things.

Link to comment
Share on other sites

  • 2 weeks later...

Having this EXACT problem now myself... where when using a Sprite (with a source image as a texture) as a mask... the mask seems to effect the alpha channel of the source texture. As I understand, stencil buffers (which I'd assume this would be using for the WebGL renderer), should only effect the inclusion/exclusion of the source pixel, not the alpha value of the pixel. 

Additionally, setting a sprite mask absolutely destroy's performance... especially on iPads... but its even noticable on desktops (huge red flag). 

Both these things are making me suspect something is fishy with the PIXI implementation... and I'll start diving into PIXI to try to see what's going on.

Is this a known issue?

Is there a better approach to leveraging the WebGL stencil buffer?

Link to comment
Share on other sites

After some PIXI diving and debugging it turns out the performance issue was due to a mis-use of the masking on our end: we needed to apply it once to a parent container instead of once per child object (~200). This removed the horrible performance hit and its ok on device now. 

As for the transparency vs inclusion/exclusion: I believe PIXI doesn't use a stencil buffer here but probably adds support for this within some shader that gets used. I suppose a multiply per pixel rather than an if is probably more performant anyway. We worked around this issue by pre-processing on load the assets used for the stencil and setting all color values of non-transparent pixels to 0xFFFFFF which then results in the behavior we want with the masking. 

So things seem ok... and I'm no longer suspicious of the implementation:)

 

However, there are of course new issues that have come up that I'm looking into atm:

- It seems masks don't work with Particle Containers. Is this a known issue? Limitation?

- Having a bug where I can't seem to resize UP the mask size on window resize... resizing down works... but not up and the old small size is used.

If anyone has any insight into the 2 issues above please let me know. 

 

Link to comment
Share on other sites

Returning to the performance question... 

I am using a sprite as a mask. The cost of applying this mask is more than I expect.

Looking a bit into the implementation it seems that setting a Sprite as a mask triggers the shader used to be the SpriteMaskFilter instead of the default Texture shader. This filter shader is quite more complex than the Texture shader which I am assuming is the main difference when I switch between setting the mask and not.

I would assume masking could use the StencilMask functionality built into WebGL instead of manually handling this in the shader. I do see the Stencil buffer is used within PIXI in places.

So my question is: is there any way to leverage the stencil buffer for performing masking with a sprite to make optimal use of the hardware acceleration? And if not... any tips I should know about for using sprites as masks?

 

 

Link to comment
Share on other sites

@MichaelZ

Basically, you just need a RenderTexture, and draw your sprites into it, then use it as a parameter for a filter, like SpriteMaskFilter does. That way you'll have all control, you'll be able to change how mask works and you wont even need the stencil buffer for it. Please dont use masks to create lighting effects, use filters.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...