pixijs / layers

Separate the z-hierarchy of your scene tree from its canonical structure.
https://pixijs.io/layers/docs/
MIT License
222 stars 57 forks source link

Attaching a DisplayList ignores mask #6

Open staff0rd opened 8 years ago

staff0rd commented 8 years ago

Something like;

this.displayList = new PIXI.DisplayList(); // if this line is present, mask ignored.
var mask = new PIXI.Graphics();
mask.beginFill(0xFFFFFF);
mask.drawRect(0, 0, 100, 100);
this.mask = mask;
var sprite = new PIXI.Sprite(someTexture);
sprite.displayGroup = new PIXI.DisplayGroup();
this.addChild(sprite);
sprite.position.set(300, 300); // visible
ivanpopelyshev commented 8 years ago

I can fix it easily, but for now, can you use two containers, assign mask to parent and displaylist to child?

staff0rd commented 8 years ago

Moving the mask to a parent worked, thanks.

kaansoral commented 8 years ago

I have a similar issue with filters, is it the same issue?

Basically, the filter isn't applied when there is a .displayGroup on the stage PIXI.Container

ivanpopelyshev commented 8 years ago

Well if you explain me how to handle that case, it willl be awesome! I just can't define the behaviour of algorithm for that

kaansoral commented 8 years ago

To an outsider, it seems like it might be a trivial issue, but I'm guessing it's not

Can you describe the challenge/problem-definition?

ivanpopelyshev commented 8 years ago

A->B->C A->D, A has displayList, C and D has same displayGroup, B has filter. That's the case. I can't put D inside B because it will be filtered, and I cant remove C from B because filter

kaansoral commented 8 years ago

It seems there was a mis-communication from my end, apologies, here is the actual issue, I don't know whether the original #6 has the same cause

stage = new PIXI.Container();

var filter=new PIXI.filters.ColorMatrixFilter()
stage.filters=[filter];
filter.desaturate(0.2);

stage.displayList = new PIXI.DisplayList(); // <- the root stage

//...

renderer.render(stage);

So, here A is stage, has displayList, has a filter, when pixi-display is applied, the filter is ineffective

-- -- -- ↓ Probably a separate challenge ↓ -- -- --

For the problem you described, I would just move C,D ignoring filters, forcing the user to structure entities manually

Let's say there is

Stage -> Map -> Map_Entities Stage -> Wisp1 Stage -> Wisp2

So let's say the Map has a filter

Map_Entities are in displayGroup1 Wisp1,Wisp2 is in displayGroup2

displayGroup2 > displayGroup1

I would structure the plugin, so displayGroup1 is forced to stay within "Map"

In this example, Wisp1, Wisp2 will always be above Map, Map_Entities, but they also have a .zOrder within themselves, Map_Entities also have a separate ordering

TL;DR: So basically, I would just dismiss the issue, let the user handle it, but provide a way to have separate well-defined pixi-display layers

kaansoral commented 8 years ago

I also just tested playing around with this line: if (container._mask || container._filters && container._filters.length || container.displayList) { - It's highly likely I don't grasp the dynamics of the situation as the result of this experimentation - so excuse my ignorance too :)

I don't get why the filter disappears when container._filters && container._filters.length is removed

ivanpopelyshev commented 8 years ago

Ok, you can just separate "stage" into two containers, "stage" and "stageInner", apply filter to stage and displaylist to inner thing. That will work. Unfortunately, filters and masks at the same component are messing with displaylist

kaansoral commented 8 years ago

Out of curiosity, does it significantly impact performance, adding another container in between?

I'm using filters mainly for fun, turning the game black and white, as it's easier on the eyes, if it impacts performance, this mode might require a restart of the game, so the intermediary is only there when needed

ivanpopelyshev commented 8 years ago

no, its a logic problem. Things in the filter/mask must be rendered in the different framebuffer/layer than anything else. So I cant jus move them between displaygroups :) if you want to use sorting inside the filter, you can add one more container inside the filter and create displayList for it, it will work separately from the main one