Jump to content

Pixi.js Sprite and Mask


clifftm
 Share

Recommended Posts

Hello again.

Please help me , how to proper use a mask inside a sprite. I'v made a codepen https://codepen.io/clf/pen/NzQgbg , when mask is on and object is moving, his borders starts twitching. But If i disable mask the object moves correctly.

So what i do wrong? How to move object with mask without shaking his border? And is it possible to make moving more smoothly (setting antialias:true in options make it moving much better, but i don't know is it a proper way)?

Thanks?

Link to comment
Share on other sites

I'm searching for about 12 hours to find proper way of simple operation - give a rectangle mask to a sprite, and move it with that mask from left to right without any distortions.

  1. if i use Sprite as Mask instead of graphics https://codepen.io/clf/pen/PaMJjM  i'v got no shaking at borders, but turn it on\off makes first sprite to look brightly\darkness, because parent alpha is applying to mask 
  2. If i put Sprite and Mask(Sprite) inside a container and move it https://codepen.io/clf/pen/rKXYdP , then all works as expected, (except antialiasing workaround of wich i will search later).
  3. If i add a blur filter to a sprite or container https://codepen.io/clf/pen/OEKOdx ,then distortions appears again, and turn on\off mask in that example blow my mind... what's happening?

So I can't put mask directly on sprite, and can't use graphics as mask, and can't use AA or Filters when want masked object?

Really, i'm trying to understand a simple things but nothing comes out...

I'v read:

  • https://github.com/pixijs/pixi.js/issues/3266 , where you said 
    Quote

    Theoretically, you can make a sprite mask, where the sprite is AA-ed graphics made from canvas with js Texture.fromCanvas(...), that'll work.

    But look at example 3 (https://codepen.io/clf/pen/OEKOdx) any filter brokes movement

  • where Bubamara said 

    Quote

    solution could be not using graphics at all. you can :

    - draw rectangle on canvas and make texture from it, then apply to sprite

    - use spritesheets as textures for rectangles (preffered, as this is faster in WebGL)

    ok. i'm going to 2d way and use PIXI.Sprite(PIXI.Texture.WHITE), and have the same troubles

  • in your fix of https://codepen.io/anon/pen/ZbVgEO?editors=0010 you add lines to a container

    Quote

      this.getLocalBounds = function() {
        return new PIXI.Rectangle(-2, -2, this.size+4, this.size+4);
      };
      this.cacheAsBitmap=true

    so as i understand the graphic rectangles in that container cached as "textures" and you increase bounds for animation to avoid jigglings, but in that example rectangles don't use masks

  • For AA most of users advises not to use {antialias:false}, because it supported only in Chrome and have performace issues. And as you said it doesn't works with masks. i'v tried {forceFXAA:true}, and stage.filters[new PIXI.filters.FXAAFilters()] with crutch of PIXI.settings.PRECISION_FRAGMENT = PIXI.PRECISION.HIGH; and nothing helps me to equal an issue.

  • and the last your advise is to look at pixi-display and learn how  https://pixijs.io/examples/#/layers/lighting.js example works and explore sources of getRenderTexture.

I wonder, that for a SIMPLEST task to make SPRITE with MASK and force it to move smoothly from x1 to x2 there is NO ways to achive that for a newbie as me =(

 

Link to comment
Share on other sites

var app = new PIXI.Application();
document.body.appendChild(app.view);

app.stage.interactive = true;

var left = new PIXI.Sprite(PIXI.Texture.WHITE);
left.width = 400;
left.height = 600;

var right = new PIXI.Sprite(PIXI.Texture.WHITE);
right.x = 400;
right.width = 400;
right.height = 600;


var maskG = new PIXI.Graphics()
//maskG.lineStyle(1,0xFF0000) <- TRY TO UNCOMMENT TO SEE DIFF
maskG.beginFill(0x555555)
maskG.drawRect(0, 0, 100, 100)    //<- COMMENT THIS
//maskG.drawRect(300, 0, 100, 100)  <- AND TRY THIS TO SEE DIF IN Y POS
maskG.endFill()

var maskS = new PIXI.Sprite(PIXI.Texture.WHITE);
maskS.y = 0;
maskS.x = 400;
maskS.width = 100;
maskS.height = 100;


left.mask = maskG;
right.mask = maskS;
app.stage.addChild(maskG,maskS,left,right);

app.ticker.add(function() {

    maskG.x += 0.1;
    maskG.y += 0.1;
  
    maskS.x += 0.1;
    maskS.y += 0.1;


});

Paste that example here https://pixijs.io/examples/#/demos/alpha-mask.js and look at the difference. Left mask is jiggling while moving, but if you uncomment maskG.lineStyle(1,0) that distortions will dissapear.

And another thing - sprite mask position offset up than graphics for about 1 px. As i understand it's possible not to add Graphic mask on the stage.addChild(), but i have to add sprite, so an example works identically with this:

app.stage.addChild(maskS,left,right);
// vs
app.stage.addChild(maskG,maskS,left,right);

So it's not clear for me, what mask is better to use? "For the moment, PIXI.CanvasRenderer doesn't support PIXI.Sprite as a mask" - is that actual information?

I like how squares moves in that example https://codepen.io/anon/pen/ZbVgEO?editors=0010, but if you try change version from 3.0.6 to 4.x that lines wont work together

  this.getLocalBounds = function() {
    return new PIXI.Rectangle(-2, -2, this.size+4, this.size+4);
  };
  this.cacheAsBitmap=true;

Look how that example works in 4.8.1 and in 5.0.0 https://codepen.io/clf/pen/Yvmovy without that lines. Is it possible to make exactly same behavior in 4.8.1 ?

I feel that devgroup concentrated on 5.0.0, and understand that implement 2 fixes in two branches is difficult, so another question : should i use 5.0.0 or it contains more bugs then 4.8.1, does 5.0.0 have backward compatibility with 4.8.1 (because i want to use DragonBonesJS wich has only 4.x PIXI support)?

Link to comment
Share on other sites

Ok. nobody want's to help with upper issue. I will post another:

Look at example in codepen https://codepen.io/clf/pen/RJXXqM :

So in that example - we have 2 containers red and yellow. Each of them contains two pixi sprites - background sprite (red 100x100 or yellow 80x80) and mask sprite (100x100 for red sprite, and 80x80 for yellow). Yellow container is a child of red container.

In v4 the result looks like this  

1.PNG.5b71b39b334248e6a908bdf263d6efeb.PNG

but in V5 the result looks like this:

2.PNG.6e077d0ed8ce37118a6a3b8ce50e18d6.PNG

You can press "<<" and ">>" buttons to move red square from 100x100 to 0x0 position, and see very very strange result. Notice, if you click on yellow "v4" area in v5 version, the mouse events will dispatch in proper bounds at same time.

Is that a bug or  "you are a stupid! read the sources"(c)?

Link to comment
Share on other sites

  • 1 month later...

Hello again ?

Was in vacation and didn't test fix for well. But in the first test with moving yellow square to the left it dissapears when touch red square border. When i move it to the right i can see only 1px verctical line instead of square. Here is an example:

https://codepen.io/clf/pen/RJXXqM

Pressing <<< will move yellow square from 10x10 to -100x10, and pressing >>> will move it to 100x10.  Didn't find any new releases from v5-alpha3 on github 

Thanks for help. 

Link to comment
Share on other sites

  • 4 weeks later...

Ok, seems nobody interested in that bug :)

Then maybe somebody could help me to understand how to apply sprite mask to a container and put the same sprite in it?

Should i always have to draw black\white mask for a sprite in a separate file, or that can be done in code for source texture? I'v tried to use filters with no luck, and didn't find anything on the forum

var c = new PIXI.Container();

var bunny = new PIXI.Sprite(texture);
var m = new PIXI.Sprite(texture);   // The equals to bunny
    
let colorMatrix = new PIXI.filters.ColorMatrixFilter();
colorMatrix.greyscale(0);
m.filters = [colorMatrix];
 	
c.mask = m;
c.addChild(m,bunny);

Thanks!

Link to comment
Share on other sites

according to the source code, mask takes only a texture and position from sprite, however you can make a renderTexture out of it first, then pass it as a mask.

As for v5 issue, I still have it in bookmarks and i posted it in our pixijs slack but no one wants to investigate it. I will add it to https://pixijs.io/v5-render-tests/ ,v5 render-tests repo, in my spare time. however I cant guarantee any fixes because I already spent  many hours on filter issues and i want someone else to take the lead now.

Link to comment
Share on other sites

22 minutes ago, ivan.popelyshev said:

according to the source code, mask takes only a texture and position from sprite, however you can make a renderTexture out of it first, then pass it as a mask.

Thanks.

But does PIXI have an instrument to transform colored sprite\texture to a proper mask or i have to draw it by myself in paint\photoshop?

Here https://github.com/pixijs/pixi.js/issues/4710 you said that mask is using alpha and red channel, so i assume the mask should looks like in attachment, and can't imagine how it can be achived only with pixi

bunny.png

The closest way i found is to use 

let colorMatrix = new PIXI.filters.ColorMatrixFilter();
m.filters = [colorMatrix];

colorMatrix.technicolor();

Then somehow to convert it to black, not pink and then somehow to inverse the result to make it like in attachment

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...