-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding framebuffer support for filter() + CreateFilterShader for 2D mode #6559
Conversation
@davepagurek the code is working for all three cases ( |
UPDATED BUILD OF THE CODE FOR CHECKING PURPOSE |
This is looking good so far! Some remaining tasks:
|
src/webgl/p5.RendererGL.js
Outdated
filter(...args) { | ||
|
||
// Treating 'pg' as a framebuffer. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can rename this from pg
? I think pg
is a holdover from Processing where and the PGraphics
class, whose p5 equivalent is p5.Graphics
. Now that we're using a framebuffer, it might be less confusing to call this something else (often in p5 and in other Web/OpenGL code you use fbo
, for "framebuffer object")
src/webgl/p5.RendererGL.js
Outdated
|
||
// Set the yScale of the filterCamera for framebuffers. | ||
if (target !== this) { | ||
this.filterCamera.yScale = this._curCamera.yScale; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're always using the filterCamera on a framebuffer now so I think its yScale should always be -1 (which is what your logic currently does as well.) But maybe a simpler way of achieving the same thing would be, when we define this.filterCamera
, to say this.filterCamera = this.getFilterGraphicsLayer().createCamera()
-- that way, its size will always match the size of the filter graphic when it resizes, and we won't need to touch its yScale
value since it will be initialized to the correct value.
src/webgl/p5.RendererGL.js
Outdated
filter(...args) { | ||
|
||
// Treating 'pg' as a framebuffer. | ||
let pg = this.getFilterGraphicsLayer(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should rename this and getFilterGraphicsLayerTemp
to not mention Graphics
any more? Maybe just getFilterLayer
and getFilterLayerTemp
?
Okay, @davepagurek can you please provide me the code where the filter(BLUR) is brekaing?? I will try to figure it out |
src/webgl/p5.RendererGL.js
Outdated
this.filterShader.setUniform('tex0', tmp); | ||
pg.clear(); | ||
pg.rect(-this.width / 2, -this.height / 2, this.width, this.height); | ||
tmp.draw(() => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right now this code is nested, which is causing this error and making it not render:
WebGL warning: drawElementsInstanced: Texture level 0 would be read by TEXTURE_2D unit 0, but written by framebuffer attachment COLOR_ATTACHMENT0, which would be illegal feedback.
I think a simplified order, without nesting and without extra copying of data, could be:
this.filterShader.setUniform('texelSize', texelSize);
this.filterShader.setUniform('canvasSize', [target.width, target.height]);
this.filterShader.setUniform('radius', Math.max(1, filterParameter));
// Horiz pass: draw `target` to `tmp`
tmp.draw(() => {
this.filterShader.setUniform('direction', [1, 0]);
this.filterShader.setUniform('tex0', target);
this._pInst.clear();
this._pInst.shader(this.filterShader);
this._pInst.rect(-target.width / 2,
-target.height / 2, target.width, target.height);
});
// Vert pass: draw `tmp` to `pg`
pg.draw(() => {
this.filterShader.setUniform('direction', [0, 1]);
this.filterShader.setUniform('tex0', tmp);
this._pInst.clear();
this._pInst.shader(this.filterShader);
this._pInst.rect(-target.width / 2,
-target.height / 2, target.width, target.height);
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For testing, I just changed filter(INVERT)
to filter(BLUR)
in your latest p5 editor link.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry @davepagurek if you come across any issues with the filter (blur), I also tested it and didn't find it breaking. but I've committed the changes, and it seems like the code is now more readable than the nested one. Thanks for your understanding
blur with nested one...from the above editor. is this not the expected behaviour??
sorry if i did'nt understood where the bug is happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe it was a browser-specific issue? in Firefox I was seeing no output on the canvas. Anyway in your most recent build it seems to be working!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, got it @davepagurek
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we no longer need this line now that we pass target
in as a uniform below
bluild of the code after the changes;- |
For this createFilterShader docs + fixes PR, should I copy all the changes into my branch and try running it locally to see whether it breaks for 2D or not without commiting any changes here? Or something else I need to do for this? If this breaks and something needs to be changed here in this PR createFilterShader docs + fixes PR then what steps should be taken?? |
src/webgl/p5.RendererGL.js
Outdated
fbo.height !== this.height | ||
) { | ||
// Resize fbo | ||
fbo.resizeCanvas(this.width, this.height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i think we'll have to do all this for tmp
too. Maybe it's worth putting this into a function, something like matchSize(fboToMatch, target)
so that you can call it on fbo
here and also on tmp
later?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay
Maybe the fastest way forward is to merge those changes into your branch and get them working with your branch? And then if they're working here, I can just close my PR, since all the updates will be in this one too. |
here's the build after merging @davepagurek https://editor.p5js.org/aman12345/sketches/Rbz3lXYlA |
If anything else needs to be changed, then please let me know @davepagurek . |
@@ -1,7 +0,0 @@ | |||
function setup() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this intentionally deleted? Otherwise I think we can keep this file around
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh... Sorry
this.clear(); | ||
this._pInst.push(); | ||
this.filterCamera._resize(); | ||
this._pInst.setCamera(this.filterCamera); | ||
this._pInst.resetMatrix(); | ||
this._pInst.image(pg, -this.width / 2, -this.height / 2, | ||
this._pInst.image(fbo, -this.width / 2, -this.height / 2, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we still need these two lines above this call:
this._pInst.imageMode(constants.CORNER);
this._pInst.blendMode(constants.BLEND);
Currently, if you change the image mode or blend mode, the filter gets drawn with an offset: https://editor.p5js.org/davepagurek/sketches/q442qjF_1
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay
I have a small question, @davepagurek . In this test, we're using WEBGL for this filter? Shouldn't we change the name from test('filter() uses WEBGL implementation behind main P2D canvas', function() {
let renderer = myp5.createCanvas(3,3);
myp5.filter(myp5.BLUR);
assert.isDefined(renderer.filterGraphicsLayer);
}); |
Only So:
All that to say, I think that test is correct as it is. |
Ooh....I was having a little confusion with this only. Thanks for your explanation. |
); | ||
} | ||
|
||
return this.filterGraphicsLayer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before this, we might want to do a similar size matching to what we do in RendererGL with its framebuffer so that we ensure this.filterGraphicsLayer
matches width, height, and pixel density to this._pInst
. Right now filters on 2D mode don't seem to work when resizing: https://editor.p5js.org/davepagurek/sketches/OOKkLOINp
Maybe we can also copy and paste the current unit test that checks that the framebuffer gets resized in WebGL mode, and adapt it to check the size of filterGraphicsLayer
in 2D mode? It would definitely be helpful to leave behind as many tests as we can so that we don't have to rely so much on thinking of new things to test the next time we make changes to this system.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
okay, i will do the changes asap.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
btw I just wanted to say thanks for your patience and continued work on this as we work through all the bugs! Hopefully it will be easier for future contributors the more tests we add, so they can rely more on those tests to let them know that they've fixed everything.
btw i need to thankyou for your patience and support. Love to have a mentor like you. |
src/core/p5.Renderer2D.js
Outdated
this.filterGraphicsLayer.height !== this.height | ||
) { | ||
// Resize the graphics layer | ||
this.filterGraphicsLayer.resize(this.width, this.height); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in this case, since filterGraphicsLayer
is a p5.Graphics
, we can use resizeCanvas
instead of resize
. Unfortunately it's kinda confusing that the main canvas and graphics call it one thing but images and framebuffers call it something else :')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oops sorry, i commited it wrong file. sorry for this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually take a look at the test for this. I am not good at writing tests.
let s = myp5.createShader(vert, frag); | ||
myp5.filter(s); | ||
myp5.resizeCanvas(5, 15); | ||
assert.equal(g1.width, 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically we only care that the sizes are equal when we want to do a filter, so you might need to call myp5.filter(s)
again before this assertion
Are we doing the correct way for test? @davepagurek |
Let me know if we need something else @davepagurek ? |
I did a little testing and agree that everything is looking good now! I think the tests are looking good. Is there anything else you can think of that we might need to add before merging? |
I will open an issue for covering all the test including filter and many more from this area. I don't think we are missing something with area of filter :) |
if everything also looks good to you then I think we're good to merge! |
I changed the heading of the issue? I think we are covering one more issue which we are merging (createFilterShader for 2D mode) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome, thanks for your work on this!
Welcome. Love to contribute more like this❤ |
Resolves #6521 #6520
Changes:
Screenshots of the change:
20231116162522.mp4
PR Checklist
npm run lint
passes