Closed bQvle closed 8 years ago
There were multiple issues with displacement. Strange, but it works in v3. May be there is something with the padding?
Might be, top and left is fine though.. i wonder if theres actually some extra black "scene overflow" before the padding. which would cause it to create black padding at bottom and right side. and it would explain the Vignette filter which clearly thinks the viewport is actually wider than it is.
and since everything is rendered from the top left corner, that would explain why the problem is bottom and right.
Lets look at https://github.com/pixijs/pixi.js/blob/dev/src/core/renderers/webgl/managers/FilterManager.js
and this https://github.com/pixijs/pixi.js/blob/dev/src/core/renderers/webgl/filters/Filter.js
and this https://github.com/pixijs/pixi.js/blob/dev/src/filters/displacement/DisplacementFilter.js
I dont think its related to Displacement, heres a screenshot with Resolution 0.01. and the streached pixel's at bottom and right shows the same issue.
Here's a sharp version of my Vignette filter, notice how it jumps around when i change the size of the window. (its supposed to be centered) it seems that something is calculated wrong somewhere. (not in the filter, but in the core viewport)
This is just minor changes to the window size, they don't translate softly, suddenly it jumps to the new location.
This is the Vignette filer
var Filter = PIXI.Filter;
function VignetteFilter(options) {
var opts = options || {};
Filter.call(this,
// vertex shader
null,
// fragment shader
fragShader,
{
size: { type: '1f', value: opts.size || 0.5 },
amount: { type: '1f', value: opts.amount || 0.5 },
focalPointX: { type: '1f', value: opts.focalPointX || 0.5 },
focalPointY: { type: '1f', value: opts.focalPointY || 0.5 }
}
);
}
VignetteFilter.prototype = Object.create(Filter.prototype);
VignetteFilter.prototype.constructor = VignetteFilter;
Object.defineProperties(VignetteFilter.prototype, {
focalPointX: {
get: function () { return this.uniforms.focalPointX; },
set: function (value) { this.uniforms.focalPointX = value; }
},
focalPointY: {
get: function () { return this.uniforms.focalPointY; },
set: function (value) { this.uniforms.focalPointY = value; }
},
size: {
get: function () {
return this.uniforms.size;
},
set: function (value) {
this.uniforms.size = value;
}
},
amount: {
get: function () {
return this.uniforms.amount;
},
set: function (value) {
this.uniforms.amount = value;
}
}
});
var fragShader = [
"precision mediump float;",
"varying vec2 vTextureCoord;",
"uniform sampler2D uSampler;",
"uniform float size;",
"uniform float amount;",
"uniform float focalPointX;",
"uniform float focalPointY;",
"void main() {",
" vec3 rgb = texture2D(uSampler, vTextureCoord).xyz;",
" float dist = distance(vTextureCoord, vec2(focalPointX, focalPointY));",
" rgb *= smoothstep(0.8, size * 0.799, dist * (0.5 * amount + size));",
" gl_FragColor = vec4(vec3(rgb), 1.0);",
"}"
].join('');
It is indeed the bug. Notice how i have aligned it perfectly here. The bugs is now gone, also the displacement bug, it streatches the border pixels nicely on all 4 edges.
Now if i make the window 1px taller (it doubles the height of the filter):
And when i make it one pixel wider (it doubles the width of the filter)
Now i can make the window lager again, until i hit the sweet spot, and things repeat.
Hope this will help you figure out whats wrong.
The vignette filter is probertly great for debugging it, it clearly shows whats happening. If you use it then set its size = 1, and amount = 1.2, then you get the vignette that fits perfectly to the window size (like above)
And please bring my drawCalls back ;)
Okay, I've found the issue. But I suspect theres a reason to why things are made this way, so I dont know the consequences of the fix.
All filters get their RenderTarget from FilterManager.getPotRenderTarget. Which obviously returns a POT resolution. (that causes the issue).
If I remove this.
minWidth = bitTwiddle.nextPow2(minWidth * resolution);
minHeight = bitTwiddle.nextPow2(minHeight * resolution);
from getPotRenderTarget, all the problems are gone. But then the name of the function is clearly not fitting anymore.
Let me know what you think
Edit: I see @GoodBoyDigital made some changes in the area 3 days ago, maybe that has something to do with it, or he properly know what to do: https://github.com/pixijs/pixi.js/commit/ae1293876de707f925f33be1ae6b40fa5dc04091
https://github.com/pixijs/pixi.js/blob/dev/src/core/renderers/webgl/filters/filterTransforms.js#L66 - there's an error there and i dont see it yet
Im really bad with Matrix,
But this looks strange
worldTransform.tx /= texture.width * translateScaleX;
//this...? free beer for anyone who can explain why this makes sense!
worldTransform.ty /= texture.width * translateScaleX;
// worldTransform.ty /= texture.height * translateScaleY;
why is both tx and ty set to /= texture.width * translateScaleX ?
Ok.
cool, Ill test it right away
sorry, there was some trash in my PR. Re-open it please, only two files are changed.
Yeah, i only took the FilterClamp stuff, it seems to work for the Displacement, trying to fix the Vignette now.
I have another issue.. (I hoped this maybe solved both), I've tried to make a simple replication but i've failed so far.
Basicly, I have an ability where a plane make a ground attack, it sprays alot of bullets with BlendMode.Add. If i use the displacementFilter at the same time, the displacementFilter breaks (the displace effect disappears, and I get a very big streched padding at left and top edges.)
The console throws ALOT of these errors at the same time
247(index):1 [.CommandBufferContext.Offscreen-MainThread-000002AE97F0D870]RENDER WARNING: there is no texture bound to the unit 1
WebGL: too many errors, no more errors will be reported to the console for this context.
Do you have any (what so ever) idea what could cause this? or should i keep trying to replicate it in a simple environment?
Btw, if i change the BlendMode to Normal on the plane bullets, theres no bug. And I'm using pixi-particles for the bullets.
Edit: aha... if I remove the VignetteFilter the bug is gone aswell.. ill try to fix the area and test again.
I just had this bug. It happens when something fails in the filter shader, I think. Are you sure VignetteFilter works like intended?
Not sure (beside that it didnt cause issues in v3), I don't really have any shader experience aswell.
how would I use otherMatrix or filterArea in this shader code?
var fragShader = [
"precision mediump float;",
"varying vec2 vTextureCoord;",
"uniform sampler2D uSampler;",
"uniform float size;",
"uniform float amount;",
"uniform float focalPointX;",
"uniform float focalPointY;",
"void main() {",
" vec3 rgb = texture2D(uSampler, vTextureCoord).xyz;",
" float dist = distance(vTextureCoord, vec2(focalPointX, focalPointY));",
" rgb *= smoothstep(0.8, size * 0.799, dist * (0.5 * amount + size));",
" gl_FragColor = vec4(vec3(rgb), 1.0);",
"}"
].join('');
DisplacementFilter passes calculateSpriteMatrix there, you can pass something like calculateNormalisedScreenSpaceMatrix, or use filterArea like TwistFilter does that.
Look inside TwistFilter how it uses filterArea.
Sorry, but I'm failing it.
When I google for Vignette filters they are all very simular to the one i use. Is there a specific reason to why the filterTexture has to round up to POT? I can only imagine that its going to make it more complicated writing filters, and "3rd-party" will not work out of the box. (and if the filter area isn't accounted for it will draw the full texture?). My monitor is 2560x1440, so in fullscreen i end up with a 4096x2048 FilterArea/RenderTarget.
It sound wrong to me.
I'm sure that all filters must take into account these things, because of padding and other issues.
Im not sure that its ok to use 4096x2048 filterarea for 2560x1440 screen, because it actually takes 2x more memory for each layer. However i think that's not important because in most applications number of big layers is 2 or 3.
Your filter looks like TwistFilter. Cant you just copy that code and insert yours? Anyway I spent the timelimit on that problem, need to actually work on my project. I'll help you later :)
I had a look at the TwistFilter and I can't figure out how to use it for the Vignette.
I tired this, but it gives me the exact same result
var fragShader = [
"uniform sampler2D uSampler;",
"uniform float size;",
"uniform float amount;",
"varying vec2 vTextureCoord;",
"uniform vec4 filterArea;",
"vec2 mapCoord( vec2 coord ) { coord *= filterArea.xy; coord += filterArea.zw; return coord; }",
"vec2 unmapCoord( vec2 coord ) { coord -= filterArea.zw; coord /= filterArea.xy; return coord; }",
"void main() {",
"vec2 coord = mapCoord(vTextureCoord);",
"coord = unmapCoord(coord);",
"vec4 color = texture2D(uSampler, coord);",
"float dist = distance(coord, vec2(0.5, 0.5));",
"color.rgb *= smoothstep(0.8, size * 0.799, dist * (amount + size));",
"gl_FragColor = color;",
"}"
].join('');
Also the TwistFilter has a Radius, and a fixed position from top left corner. I think it works with the same Area (from vTextureCoord) 4096x2048. but I dont know.
edit: Sorry if im repeating myself, but what was the reason that the filter RenderTaget have to be POT?. FilterManager.getPotRenderTarget. <- changing that to not return POT also fixes the "black" padding bug. And then I would have a 2560x1440 RenderTarget insted of 4096x2048, and the standard vignette filter would fit out of the box.
texture2d(uSampler, vTextureCoord) is totally ok. but for distance you have to use unmapped coord, that's what its all about :)
this just makes the screen pitch black
var fragShader = [
"uniform sampler2D uSampler;",
"uniform float size;",
"uniform float amount;",
"varying vec2 vTextureCoord;",
"uniform vec4 filterArea;",
"vec2 unmapCoord( vec2 coord ) { coord -= filterArea.zw; coord /= filterArea.xy; return coord; }",
"void main() {",
"vec4 color = texture2D(uSampler, vTextureCoord);",
"float dist = distance(unmapCoord(vTextureCoord), vec2(0.5, 0.5));",
"color.rgb *= smoothstep(0.8, size * 0.799, dist * (amount + size));",
"gl_FragColor = color;",
"}"
].join('');
try "distance(vTextureCoord - filterArea.zw / filterArea.xy, vec2(0.5, 0.5)"
Unfortunately, It does the same POW2 snapping
Oh, right, filterArea is not for that kind of things :))) I know what to do with it, I'll help you tomorrow, its 4:48AM here.
Thats okay :) thanks alot for your effort! (but i still wonder if it actually draws the full 4096x2048 RenderTaget with a 2560x1440 resoluion, that still can't be good)
nah, its 2560x1440, it doesnt draw all these black pixels
I'm still trying to replicate my bug, but I think I found another bug. seems like the entire stage becomes a displacement filter, and it has a stange behavior when you add multiple displacement filters. (or maby it just have troubles with multiple filters on the same container)
Try use the following code for this example: http://pixijs.github.io/examples/index.html?s=filters&f=displacement-map.js&title=Displacement%2BMap&v=dev
I've added Vignette to it, so you can test the shader with it aswell. (press the canvas, and it spawns ripples, notice what happends when you press multiple times. All the maggots looks like they have a normal-map) If you change the Vignette size to 1, you can see very clearly that the maggots displacement is actually appied on top of the filters. even though they are not a displamentmap.
"var vignetteFilter = new VignetteFilter({size: 1, amount: 1});"
Also, try and remove the VignetteFilter, and check out the Grass color, something wrong is happening with that aswell.
function VignetteFilter(options) {var opts = options || {};PIXI.Filter.call(this,null,fragShader,{size: { type: '1f', value: opts.size || 0.5 },amount: { type: '1f', value: opts.amount || 0.5 }});} VignetteFilter.prototype = Object.create(PIXI.Filter.prototype);VignetteFilter.prototype.constructor = VignetteFilter;Object.defineProperties(VignetteFilter.prototype, {size: { get: function () {return this.uniforms.size;},set: function (value) {this.uniforms.size = value;}},amount: {get: function () {return this.uniforms.amount;},set: function (value) {this.uniforms.amount = value;}}});
var fragShader = [
"uniform sampler2D uSampler;",
"uniform float size;",
"uniform float amount;",
"varying vec2 vTextureCoord;",
"uniform vec4 filterArea;",
"void main() {",
"vec4 color = texture2D(uSampler, vTextureCoord);",
"float dist = distance(vTextureCoord - filterArea.zw / filterArea.xy, vec2(0.5, 0.5));",
"color.rgb *= smoothstep(0.8, size * 0.799, dist * (amount + size));",
"gl_FragColor = color;",
"}"
].join('');
filters = [];
function addFilter(f){
filters.push(f);
stage.filters = filters;
}
function removeFilter(f){
filters.splice(filters.indexOf(f),1);
if (filters.length <= 0)
stage.filters = undefined;
else
stage.filters = filters;
}
var ripples = [];
function ripple() {
this.donutScale = 0;
this.sprite = PIXI.Sprite.fromImage('http://i.imgur.com/OfOCy3G.png');
this.sprite.anchor.set(0.5);
this.displacementFilter = new PIXI.filters.DisplacementFilter(this.sprite);
stage.addChild(this.sprite);
ripples.push(this);
addFilter(this.displacementFilter);
this.sprite.position.copy(mousePosition);
this.update = function(){
if (this.donutScale < 10) {
this.donutScale += 0.1;
this.sprite.scale.set(this.donutScale);
this.displacementFilter.scale.set(120 - (120 * (this.donutScale / 10)));
if (this.donutScale >= 10)
this.remove();
}
},
this.remove = function() {
ripples.splice(ripples.indexOf(this), 1);
removeFilter(this.displacementFilter);
}
}
document.addEventListener("click", function() {
new ripple();
});
var renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);
// create the root of the scene graph
var stage = new PIXI.Container();
stage.interactive = true;
var mousePosition = new PIXI.Point();
stage.on('mousemove', onPointerMove).on('touchmove', onPointerMove);
function onPointerMove(eventData) { mousePosition.copy(eventData.data.global);}
var container = new PIXI.Container();
stage.addChild(container);
var vignetteFilter = new VignetteFilter({size: 0.2, amount: 1});
addFilter(vignetteFilter);
var bg = PIXI.Sprite.fromImage('_assets/bkg-grass.jpg');
bg.width = renderer.width;
bg.height = renderer.height;
bg.alpha = 0.4;
container.addChild(bg);
var padding = 100;
var bounds = new PIXI.Rectangle(-padding, -padding, renderer.width + padding * 2, renderer.height + padding * 2);
var maggots = [];
for (var i = 0; i < 1000; i++)
{
var maggot = PIXI.Sprite.fromImage('_assets/maggot.png');
maggot.anchor.set(0.5);
container.addChild(maggot);
maggot.direction = Math.random() * Math.PI * 2;
maggot.speed = 1;
maggot.turnSpeed = Math.random() - 0.8;
maggot.position.x = Math.random() * bounds.width;
maggot.position.y = Math.random() * bounds.height;
maggot.scale.set(1 + Math.random() * 0.3);
maggot.original = maggot.scale.clone();
maggot.blendMode = 1;
maggots.push(maggot);
}
var count = 0;
function animate() {
for (var i = ripples.length - 1; i >= 0; i--) {
ripples[i].update();
}
count += 0.05;
for (var i = 0; i < maggots.length; i++)
{
var maggot = maggots[i];
maggot.direction += maggot.turnSpeed * 0.01;
maggot.position.x += Math.sin(maggot.direction) * maggot.speed;
maggot.position.y += Math.cos(maggot.direction) * maggot.speed;
maggot.rotation = -maggot.direction - Math.PI/2;
maggot.scale.x = maggot.original.x + Math.sin(count) * 0.2;
// wrap the maggots around as the crawl
if (maggot.position.x < bounds.x)
maggot.position.x += bounds.width;
else if (maggot.position.x > bounds.x + bounds.width)
maggot.position.x -= bounds.width;
if (maggot.position.y < bounds.y)
maggot.position.y += bounds.height;
else if (maggot.position.y > bounds.y + bounds.height)
maggot.position.y -= bounds.height;
}
renderer.render(stage);
requestAnimationFrame(animate);
}
animate();
And I replicated my bug now :)
If you remove this line:
maggot.blendMode = 1;
so with normal blendMode
The bug with broken displacementFilter, ugly padding and RENDER WARNING happens!
Its like really stange things is happending with a certain mix of Filters and BlendModes. and it didn't happend with V3, so it must be some of the new filter changes.
Actually it might be because the entire Stage becomes an invalid displacement-map
No, if I remove that line, everything works fine like before. Except that its not centered properly of course :)
Ok, displacement is fixed&merged. I'll help you with Vignette in my free time.
hmm, that doesn't make sense, Take a look what happends for me:
One click: (everyting looks as it should)
Two clicks: (All maggots become displaced, or something bleeds through the vignette)
Normal BlendMode and Vignette "size = 0.2" (no ripples and padding / render warning bug + maggots still gets "shiny/displaced")
And the Grass
The grass on first and second image might be same color (but you get the illusion of it beeing darker because the maggots blend mode break somhow (dark squares))
Without Vignette And normal Blendmode (removes padding bug) but still has grass bug with multiple ripples.
I don't understand if you don't have any of this (are u testing with the official url on v4 dev?) I have the bugs in both firefox and chrome.
Update: Its the (0.4) alpha of the grass that breaks with multiple ripples. Its like things just begins to fall apart when multiple filters i applied
Have you had a chance to look into this bug? I've testet from several computers / browsers and they all have the same wrong behaviour.
Im working on pixi-tilemap currently. You documented that behaviour enough that I'm sure i'll fix it this week.
Cool :) gl and have fun!
Just a suggestion, I know you wanna seperate things to plugins. but I would add Vignette to the default filter pack / plugin. Its' much more common used/usable then many of the current filters.
Hey! I finished with pixi-tilemap, but rpgmaker MV has that sound problem, and I know that you know something about Web Audio, and I really need help with that thing :)
Shader:
var fragShader = [
"uniform sampler2D uSampler;",
"uniform float size;",
"uniform float amount;",
"uniform float strength;",
"varying vec2 vTextureCoord;",
"uniform vec4 filterSourceSize;",
"uniform vec4 filterSourceOffset;",
"void main() {",
"vec4 color = texture2D(uSampler, vTextureCoord);",
"float dist = distance((vTextureCoord - filterSourceOffset.zw) / filterSourceSize.zw, vec2(0.5, 0.5));",
"color.rgb *= smoothstep(0.8, size * 0.799, dist * (strength * amount + size));",
"gl_FragColor = color;",
"}"
].join('');
Fixed filter
function VignetteFilter(options) {
var opts = options || {};
PIXI.Filter.call(this,null,fragShader);
this.uniforms.amount = opts.amount || 0.5;
this.uniforms.size = opts.size || 0.5;
this.uniforms.mappedMatrix = new PIXI.Matrix();
}
VignetteFilter.prototype = Object.create(PIXI.Filter.prototype);VignetteFilter.prototype.constructor = VignetteFilter;Object.defineProperties(VignetteFilter.prototype, {size: { get: function () {return this.uniforms.size;},set: function (value) {this.uniforms.size = value;}},amount: {get: function () {return this.uniforms.amount;},set: function (value) {this.uniforms.amount = value;}}});
VignetteFilter.prototype.apply = function (filterManager, input, output)
{
filterManager.calculateNormalizedScreenSpaceMatrix(this.uniforms.mappedMatrix);
// draw the filter...
filterManager.applyFilter(this, input, output);
};
var fragShader = [
"uniform sampler2D uSampler;",
"uniform float size;",
"uniform float amount;",
"varying vec2 vTextureCoord;",
"uniform mat3 mappedMatrix;",
"void main() {",
"vec4 color = texture2D(uSampler, vTextureCoord);",
"vec3 mapCoord = vec3(vTextureCoord, 1.0) * mappedMatrix;",
"float dist = distance(mapCoord.xy, vec2(0.5, 0.5));",
"color.rgb *= smoothstep(0.8, size * 0.799, dist * (amount + size));",
"gl_FragColor = color;",
"}"
].join('');
filters = [];
function addFilter(f){
filters.push(f);
stage.filters = filters;
}
function removeFilter(f){
filters.splice(filters.indexOf(f),1);
if (filters.length <= 0)
stage.filters = undefined;
else
stage.filters = filters;
}
var ripples = [];
function ripple() {
this.donutScale = 0;
this.sprite = PIXI.Sprite.fromImage('http://i.imgur.com/OfOCy3G.png');
this.sprite.anchor.set(0.5);
this.displacementFilter = new PIXI.filters.DisplacementFilter(this.sprite);
stage.addChild(this.sprite);
ripples.push(this);
addFilter(this.displacementFilter);
this.sprite.position.copy(mousePosition);
this.update = function(){
if (this.donutScale < 10) {
this.donutScale += 0.1;
this.sprite.scale.set(this.donutScale);
this.displacementFilter.scale.set(120 - (120 * (this.donutScale / 10)));
if (this.donutScale >= 10)
this.remove();
}
},
this.remove = function() {
ripples.splice(ripples.indexOf(this), 1);
removeFilter(this.displacementFilter);
}
}
document.addEventListener("click", function() {
new ripple();
});
var renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);
// create the root of the scene graph
var stage = new PIXI.Container();
stage.interactive = true;
var mousePosition = new PIXI.Point();
stage.on('mousemove', onPointerMove).on('touchmove', onPointerMove);
function onPointerMove(eventData) { mousePosition.copy(eventData.data.global);}
var container = new PIXI.Container();
stage.addChild(container);
var vignetteFilter = new VignetteFilter({size: 0.2, amount: 1});
addFilter(vignetteFilter);
var bg = PIXI.Sprite.fromImage('_assets/bkg-grass.jpg');
bg.width = renderer.width;
bg.height = renderer.height;
bg.alpha = 0.4;
container.addChild(bg);
var padding = 100;
var bounds = new PIXI.Rectangle(-padding, -padding, renderer.width + padding * 2, renderer.height + padding * 2);
var maggots = [];
for (var i = 0; i < 1000; i++)
{
var maggot = PIXI.Sprite.fromImage('_assets/maggot.png');
maggot.anchor.set(0.5);
container.addChild(maggot);
maggot.direction = Math.random() * Math.PI * 2;
maggot.speed = 1;
maggot.turnSpeed = Math.random() - 0.8;
maggot.position.x = Math.random() * bounds.width;
maggot.position.y = Math.random() * bounds.height;
maggot.scale.set(1 + Math.random() * 0.3);
maggot.original = maggot.scale.clone();
// maggot.blendMode = 1; - IT WORKS THAT WAY
maggot.blendMode = 0; // DOESNT WORK THAT WAY
maggots.push(maggot);
}
var count = 0;
function animate() {
for (var i = ripples.length - 1; i >= 0; i--) {
ripples[i].update();
}
count += 0.05;
for (var i = 0; i < maggots.length; i++)
{
var maggot = maggots[i];
maggot.direction += maggot.turnSpeed * 0.01;
maggot.position.x += Math.sin(maggot.direction) * maggot.speed;
maggot.position.y += Math.cos(maggot.direction) * maggot.speed;
maggot.rotation = -maggot.direction - Math.PI/2;
maggot.scale.x = maggot.original.x + Math.sin(count) * 0.2;
// wrap the maggots around as the crawl
if (maggot.position.x < bounds.x)
maggot.position.x += bounds.width;
else if (maggot.position.x > bounds.x + bounds.width)
maggot.position.x -= bounds.width;
if (maggot.position.y < bounds.y)
maggot.position.y += bounds.height;
else if (maggot.position.y > bounds.y + bounds.height)
maggot.position.y -= bounds.height;
}
renderer.render(stage);
requestAnimationFrame(animate);
}
animate();
I think i found the bug with the new calculatedMatrix.
var calculateNormalizedScreenSpaceMatrix = function (outputMatrix, filterArea, textureSize) {
var texture = { width: 800, height: 600 };//sprite._texture.baseTexture;
var translateScaleX = (textureSize.width / texture.width);
var translateScaleY = (textureSize.height / texture.height);
The reason it was fixed was because of the 800x600. don't know how its ment to work. but maybe just delete the texture and use filterArea width and height.
var translateScaleX = (textureSize.width / filterArea.width);
var translateScaleY = (textureSize.height / filterArea.height);
This works for Vignette
So, this thing is fixed and merged, we can close it :)
OK, filters are still wrong, please look at my code, post it in examples, use latest-dev-v4 and click somewhere. Look in the console too. Notice that with blendMode=1 it works while 0 fails. Something with SpriteRenderer
Yes, and in my usage scenario it acts the oppsite. Blendmode = 1 will fail, blendmode 0 doesn't. Also notice the blendmode of the maggots is broken when the example loads. (they all get black boxes) when you click once (add one displacement ripple) the blendmode of the maggots is fixed while it lasts.
Ok, and now we still have blinking when clicking on it. Something is clearly wrong, sprite.updateTransform() inside ripple didnt help
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
When using displacement, it will pull in "black void" from bottom and right edge. Top and Left edge pulls in a streached version of the outer pixel (which v3 did for all edges).
I'm using a Vigette filter aswell, and Its only visible at the left side of the screen. Its like it thinks the stage is actually wider than it is. so the vignette eclipse is not centered.
something like this (Only V4 aswell)
Maybe these things are related.
Edit: You can see it in your demo aswell (put the magnifier to the bottom or right edge, still only v4) http://pixijs.github.io/examples/index.html?s=filters&f=displacement-map.js&title=Displacement%2BMap&v=dev