Sechgulo

Masking + RenderTexture and its positioning

Recommended Posts

Hi, first post and very new to PIXI!

I'm trying to figure out how positioning works and how to do it properly.
I have a few followup questions which I'll take later.

Goal: Having a centered "mask area" where I can count the "unmasking progress"

But first off; here is a fiddle.
As you can see I have a centerContainer which I add all my sprites and bind all interactivity to. I center all the sprites relative to the app width and height values. I create the renderTexture with the same width and height as onTopOfMask and imageToReveal (400x400). 
The renderTextureSprite is not positioned and it results in only a corner being "unmasked" (clearly visible if I comment out the masking, it's positioned top left). If I position renderTextureSprite (fiddle) the same way as I've done with the sprites it works but then the brush/unmasking has some weird offset.

1. Is that the way to properly center the sprites etc or is it better to center the container instead? (like so: fiddle) or any other way?

2. When positioning, why does the mask have a weird offset? 

Fiddling around but not getting any wiser so help is greatly appriciated!

Share this post


Link to post
Share on other sites

Yes, you need to position renderTextureSprite, as for brush, you have to use local position relative to renderTextureSprite left-top position, because you want to render brush inside of that texture.

Yes, I know that (0,0) of mask sprite is actually center of screen, but I wont use it here, what if you want to scale/rotate it or do other kind of transfirn operation?

renderTextureSprite.toLocal(event.data.global, undefined, brush);
brush.x += renderTextureSprite.anchor.x * renderTexture.width;
brush.y += renderTextureSprite.anchor.y * renderTexture.height;

First we take get coordinate in sprite space, then we shift it by anchor, because that's how anchor works for sprite - it just shifts the texture.

masking_explanation.jpg

Share this post


Link to post
Share on other sites

For your case I suggest to use canvas2d API for drawing, instead of that.

drawingCanvas = document.createElement("canvas");
drawingContext = drawingCanvas.getContext("2d");

pixiTexture = PIXI.Texture.fromCanvas(drawingCanvas);


function drawBrush() {
  drawingContext.drawCircle(); //I dont remember API, please consult MDN

//you want to count pixels
  var imageData = drawingContext.getImageData(0, 0, w,h);
  for (i=0;i<imageData.data.length; i+=4) { ... }

//upload drawingCanvas to pixi
  pixiTexture.baseTexture.update();

}

EXTRACT is much slower than texture upload from memory to GPU. So it'll be better if you do manipulations on Canvas2d site , count pixels, then upload it.

One more trcik to make drawing in pixi faster: draw the grass to drawingCanvas, and ERASE it with special globalCompositionMode (please consult MDN) https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation

That way you wont need mask - you just put drawing sprite on top of revealing sprite, and initially grass just rendered over the sprite.

Share this post


Link to post
Share on other sites

@ivan.popelyshev AWESOME!

I knew it was something logical, was going crazy there for a while.
Thank you very much!

Now a followup question:
How would I go about using another image as the "renderTexture", so instead of using WxH pixel values use an image instead and therefor being able to count pixels that are not just 400x400. Here is a fiddle with updated assets. Hope that makes sense, not sure how to explain it..

Share this post


Link to post
Share on other sites

Hi again @ivan.popelyshev

Picked this up again and I'm curious and stubborn to make it work fully with PIXI before I try the canvas2d API.
One thing that I can't figure out. When rapidly moving the mouse (while pointerdown) across the area, the move event seems to not be updating quickly enough which results in "gaps". It's visible if you drag/move quickly in this example, here's also an image that explains what I mean.

If I log event.data.global I can in fact see that the registered position is "jumping", i.e. position Y can between events be greater then the brush size which gives those gaps. Tried messing with the InteractionManagers interactionFrequency property but with no effect. I just want to understand why its not registering at a necessary frequency. Is there something obvious or how would I go about solving this, some interpolation?

Thanks

Share this post


Link to post
Share on other sites

Ok, bare with me but in terms of interpolation, would that mean making multiple render calls during the same event with adjusted brush positioning, or whats my thinking? (Trying to grasp what interpolation entails in this scenario)
 

Share this post


Link to post
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...

  • Recently Browsing   0 members

    No registered users viewing this page.