phaser3-rex-notes
phaser3-rex-notes copied to clipboard
Drop Shadow pipeline broken in Phaser 3.70
Updated Phaser to 3.70, as well as rex plugin to 1.60.7, and enabling the Drop Shadow pipeline on a game object leads to odd flickering of the resolution.
Here is an example, moving before and after applying the pipeline (the black line has the pipeline applied to it):
https://github.com/rexrainbow/phaser3-rex-notes/assets/9264791/90fee911-bcd1-4504-a84c-fff363e3bfb3
Can't reproduce this case.
Here is my test case :
- Click any position inside background image to move sprite
- Apply drop shadow post-fx effect when moving start
- Remove drop shadow post-fx effect when moving stop (reach to target position)
Running on chrome, no flickering occurs.
Hey @LaP0573 , hey @rexrainbow ,
Interesting! I'm facing the exact same issue is Maxime on a very similar project (hello Gather friends!)
Capture vidéo du 2023-11-24 15-21-07.webm
For me, it is the "rexOutlinePipeline" that makes this error.
We are initializing the plugin a bit differently (from the Game config) this way:
https://github.com/workadventure/workadventure/blob/95b5f3ed8c329997c5d3f081b9655f6cd75c0daf/play/src/svelte.ts#L154
Could it be related? (also, we are using the last tagged version of rex plugin which seems to be different from the one used in the Codepen that is not yet tagged)
@moufmouf Can't reproduce your case neither. ( my test code, it has camera scrolling ).
Mmmh very odd, one detail is that we're applying the shader to Phaser.GameObject.Line
objects (which @moufmouf is not so I'm unsure it's related, but figured I'd point it out just in case)
Hey @rexrainbow ,
Thanks a lot for being so reactive, you are awesome.
Looking at your example, I can actually reproduce the issue sometimes. It does look exactly the same but on the first click to move the object, there seems to be a single frame with glitches in it.
See:
Capture vidéo du 2023-11-24 17-40-44.webm
(the glitch really happens only on the first frame in your example but happens all over the place on our side)
Also, I noticed this happens in Chrome, but not in Firefox (though in Firefox, the effect seems to fail silently sometimes)
I'd be happy to help debug this further, but I'm not sure where to look...
Mmmh very odd, one detail is that we're applying the shader to
Phaser.GameObject.Line
objects (which @moufmouf is not so I'm unsure it's related, but figured I'd point it out just in case)
Can't reproduce by Line game object neither. Tested on
- os : window 11
- browser : chrome, firefox
@moufmouf I still can't reproduce that glitch bug in my site.
Here is a shadow effect by built-in shadow effect (gameObject.postFX.addShadow(...)
), any click to move this game object.
Could you check the render result in your environment?
Hey @rexrainbow ,
Thanks a lot for being so reactive, you are awesome.
Looking at your example, I can actually reproduce the issue sometimes. It does look exactly the same but on the first click to move the object, there seems to be a single frame with glitches in it.
See:
Capture.video.du.2023-11-24.17-40-44.webm (the glitch really happens only on the first frame in your example but happens all over the place on our side)
Also, I noticed this happens in Chrome, but not in Firefox (though in Firefox, the effect seems to fail silently sometimes)
I'd be happy to help debug this further, but I'm not sure where to look...
I encountered the same glitches issue.It seems that the first frame after adding a postfx will be randomly painted.
Temporally fixed by overriding the postBatch
method of the PostFXPipeline
class:
Phaser.Renderer.WebGL.Pipelines.PostFXPipeline.prototype.postBatch = function(gameObject) {
if (!this.hasBooted) {
this.bootFX();
} else {
this.onDraw(this.currentRenderTarget);
}
//
this.onPostBatch(gameObject);
return this;
};
@tongliang999 The original logic of postBatch
method is
postBatch: function (gameObject)
{
if (!this.hasBooted)
{
this.bootFX();
}
this.onDraw(this.currentRenderTarget);
this.onPostBatch(gameObject);
return this;
},
It seems a bug in phaser3 engine.
In your patch logic, onDraw
method won't call if not hasBooted
.
Because that I can't reproduce the glitch rendering result, I can't open an issue for this case on phase3's repo.
Hey @tongliang999 ,
You are right, it is indeed only the first frame after adding a Postfx that has the issue. Because of pretty hard core optimizations I do to avoid useless rendering, it is more visible in my code than elsewhere (I'm stopping the rendering if nothing moves). If I disable those optimizations, I see exactly what you see: just after adding an effect, the first frame has a random glitch.
I managed to make it obvious in the codepen below: on each frame, I either set up the Postfx plugin or remove it.
https://codepen.io/moufmouf/pen/abXjYRV
It definitely looks like a bug in Phaser 3.
@tongliang999 The original logic of
postBatch
method ispostBatch: function (gameObject) { if (!this.hasBooted) { this.bootFX(); } this.onDraw(this.currentRenderTarget); this.onPostBatch(gameObject); return this; },
It seems a bug in phaser3 engine. In your patch logic,
onDraw
method won't call if nothasBooted
. Because that I can't reproduce the glitch rendering result, I can't open an issue for this case on phase3's repo.
The problem is that the bootFX
method does everything that the pipeline needs in order for onDraw
to work. So the logic is correct if we assume that WebGLPipeline.boot
does indeed do all that we need to render, which I believe it does - this is likely why we don't see this manifest on desktops. However, this patch introduces an artificial frame skip. Perhaps something in the boot process it taking longer than a frame to occur, which is why on the second pass, everything is ok.
I can't see a reason to modify postBatch
(I don't think it's the root of the issue), but equally it won't break anything either and will still carry on working on desktops, so we can give it a try in v3.80.
I can confirm your fix works.
Also: the issue happened not only on mobile, but also on desktop in my case (in Chrome only).
:100: I'm so happy I'll finally be able to upgrade Phaser and get the nice features of 3.70!
@tongliang999 The original logic of
postBatch
method ispostBatch: function (gameObject) { if (!this.hasBooted) { this.bootFX(); } this.onDraw(this.currentRenderTarget); this.onPostBatch(gameObject); return this; },
It seems a bug in phaser3 engine. In your patch logic,
onDraw
method won't call if nothasBooted
. Because that I can't reproduce the glitch rendering result, I can't open an issue for this case on phase3's repo.The problem is that the
bootFX
method does everything that the pipeline needs in order foronDraw
to work. So the logic is correct if we assume thatWebGLPipeline.boot
does indeed do all that we need to render, which I believe it does - this is likely why we don't see this manifest on desktops. However, this patch introduces an artificial frame skip. Perhaps something in the boot process it taking longer than a frame to occur, which is why on the second pass, everything is ok.I can't see a reason to modify
postBatch
(I don't think it's the root of the issue), but equally it won't break anything either and will still carry on working on desktops, so we can give it a try in v3.80.
@photonstorm Thanks for your reply.
After some deep diving in the source code, I have found that not invoking this.currentRenderTarget.bind()
is the cause of the first frame glitch.
In the normal run,currentRenderTarget.bind()
is called in WebGLPipeline.preBatch
. Due to delayed call of bootFx
(in PostFXPipeline.postBatch
), currentRenderTarget.bind()
is not called before drawing the first frame.
I fix this by adding this.currentRenderTarget.bind()
after this.bootFx()
, it wokrs well on desktop chrome. And it wont introduce any frame skip.
postBatch: function (gameObject)
{
if (!this.hasBooted)
{
this.bootFX();
if (this.currentRenderTarget)
{
this.currentRenderTarget.bind();
}
}
this.onDraw(this.currentRenderTarget);
this.onPostBatch(gameObject);
return this;
},
Hey @tongliang999
Whoa, so cool! You nailed it. :heart: I took the liberty to open a PR with your solution here: https://github.com/phaserjs/phaser/pull/6728
@photonstorm, hope can merge this before 3.80! :+1: