Skip to content
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

Canvas becomes strange when using translate() and filter function in 2D mode #6502

Closed
1 of 17 tasks
inaridarkfox4231 opened this issue Oct 27, 2023 · 18 comments · Fixed by #6503
Closed
1 of 17 tasks

Canvas becomes strange when using translate() and filter function in 2D mode #6502

inaridarkfox4231 opened this issue Oct 27, 2023 · 18 comments · Fixed by #6503

Comments

@inaridarkfox4231
Copy link
Contributor

inaridarkfox4231 commented Oct 27, 2023

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build Process
  • Unit Testing
  • Internalization
  • Friendly Errors
  • Other (specify if possible)

p5.js version

1.8.0

Web browser and version

Chrome

Operating System

Windows11

Steps to reproduce this

Steps:

  1. createCanvas(600, 600); background(255); noStroke(); fill(0); translate(300, 300); circle(0, 0, 300);
  2. and then, apply filter(BLUR, 5);
  3. become looks strange.

Snippet:

function setup() {
  createCanvas(600, 600);
  background(255);
  noStroke();
  fill(0);
  translate(300, 300);
  circle(0, 0, 300);
  filter(BLUR, 5);
}

2D_BLUR_BUG

version 1.7.0

BLUR_170

version 1.8.0

BLUR_180

@inaridarkfox4231
Copy link
Contributor Author

sorry. This happens with any filter function. So I changed the title.

case INVERT: (version 1.8.0)
INVERT

@inaridarkfox4231 inaridarkfox4231 changed the title Canvas becomes strange when using translate() and filter(BLUR) in 2D mode Canvas becomes strange when using translate() and filter function in 2D mode Oct 27, 2023
@inaridarkfox4231
Copy link
Contributor Author

In addition, the behavior when drawing with lower opacity seems to be different from that in 1.7.0.

APPLY_FILTER_TO_ALPHA

snipet

let img;

function preload(){
  img = loadImage("https://inaridarkfox4231.github.io/assets/season/summer_small.png");
}
function setup(){
  createCanvas(img.width, img.height);
  background(img, 64);
  filter(~~~);
}

version 1.7.0

BLUR_64_170

INVERT_64_170

OPAQUE_64_170

version 1.8.0

BLUR_64_180

INVERT_64_180

OPAQUE_64_180

However, if "this" is the future behavior of 2D filter(), this is not considered a bug, so there is no problem.

@davepagurek
Copy link
Contributor

It looks like all of the bug behaviour happens here:

this._pInst.push();
this._pInst.noStroke();
this._pInst.image(pg, -this.width/2, -this.height/2,
this.width, this.height);
this._pInst.pop();

  • We probably shouldn't assume an image mode and should explicitly add imageMode(CORNER)
  • We probably should clear the canvas first so that we don't blend with the earlier canvas
  • Speaking of blending, we should probably not assume a blend mode and explicitly add blendMode(BLEND)

@Garima3110
Copy link
Contributor

Hey @davepagurek , I am interested in working on this issue. Could you please add some more context to what you are trying to say through this:

  • We probably shouldn't assume an image mode and should explicitly add imageMode(CORNER)
  • We probably should clear the canvas first so that we don't blend with the earlier canvas
  • Speaking of blending, we should probably not assume a blend mode and explicitly add blendMode(BLEND)

ThankYou!

@perminder-17
Copy link
Contributor

It looks like all of the bug behaviour happens here:

this._pInst.push();
this._pInst.noStroke();
this._pInst.image(pg, -this.width/2, -this.height/2,
this.width, this.height);
this._pInst.pop();

  • We probably shouldn't assume an image mode and should explicitly add imageMode(CORNER)
  • We probably should clear the canvas first so that we don't blend with the earlier canvas
  • Speaking of blending, we should probably not assume a blend mode and explicitly add blendMode(BLEND)

Thankyou for your suggestion @davepagurek

@Garima3110 Garima3110 mentioned this issue Oct 28, 2023
3 tasks
@inaridarkfox4231
Copy link
Contributor Author

For reference, here is an example:
Transparency becomes an issue when pasting transparent images. There may not be many examples like this, but if the background is transparent and INVERT is applied, it seems that with the current specifications, it will be colored.

function setup() {
  createCanvas(400, 400);
  let gr=createGraphics(100,100);
  gr.textAlign(CENTER,CENTER);
  gr.textSize(80);
  gr.text("🦊",50,50);
  gr.filter(INVERT);

  background(128);
  image(gr,100,100);
}

version 1.7.0

INVERT_170

version 1.8.0

INVERT_180

@inaridarkfox4231
Copy link
Contributor Author

Finally, this is not a bug report, just a chat, but there seems to be a slight difference in the behavior of BLUR when the background is transparent in 2D and webgl.

function setup(){
  createCanvas(400, 400);
  clear();
  textAlign(CENTER, CENTER);
  textSize(180);
  text("🐬",200,200);
  filter(BLUR, 10, true/false);
}

use webglFilter

FILTER_BLUR_true_2

not use webglFilter

FILTER_BLUR_false_2

These are the points that I was concerned about about the filter function that was implemented this time. I'll leave it to you to decide what to do with these. In the p5.js community to which I belong, even the first thing I raised is not considered a bug. So I can't determine whether these are bugs or not. So I'll leave everything to you regarding to handle these.

@SableRaf
Copy link
Contributor

SableRaf commented Oct 30, 2023

Hey @inaridarkfox4231 thanks for your reports. I'd suggest filing separate issues for each unexpected behavior you noticed as they most likely have different causes. This will make it easier to track the issues and possible solutions.

@inaridarkfox4231
Copy link
Contributor Author

inaridarkfox4231 commented Oct 30, 2023

I got it. Let's separate the transform issue and transparency issue.
It appears that the problem with the transform operation is on the verge of being resolved.
Therefore, let's have this resolved in the relevant pull request (#6503).
The transparency issue has nothing to do with that, so let's raise a separate issue.
Thanks,

@inaridarkfox4231
Copy link
Contributor Author

Regarding "blur", I think this is a subjective issue as it is a question of how to define "blur". I can't decide whether or not it should be treated as a bug, so I'll leave everything up to the person who created the specifications.

@inaridarkfox4231
Copy link
Contributor Author

Because they look so different. This is no longer a question of what is the correct way to define BLUR, but how to define a new BLUR.
And since that conclusion seems to have been reached, there may be no need to make it an issue. It looks different, but it's probably correct.

function setup() {
  createCanvas(400, 400);

  let gr=createGraphics(400,400,WEBGL);
  
  gr.clear();
  gr.noStroke();
  gr.fill("red");
  gr.lights();
  gr.push();
  gr.rotateX(0.5);
  gr.rotateY(0.6);
  gr.rotateZ(0.2);
  gr.box(100);
  gr.pop();

  image(gr,0,0);

  filter(BLUR, 20, true/false);
}

version 1.7.0 BLUR

WEBGL_BLUR170

version 1.8.0 BLUR

WEBGL_BLUR180

@davepagurek
Copy link
Contributor

I think the blur issue is the same as the transparency one, as it only happens when the background is not fully opaque (adding background(255) before image(...) looks pretty normal.) we can try to fix that along with the transparency issue.

@inaridarkfox4231
Copy link
Contributor Author

I agree. It seems like the issue is how to handle transparency. It may be necessary to modify the shader.

@davepagurek
Copy link
Contributor

For dealing with the transformation of the canvas, I think we need to make sure we call this._pInst.resetMatrix() (as opposed to pg.resetMatrix() -- the main canvas is the one whose transformations might need to be reset.) We might also need to create a filterCamera on the renderer so that we always have around a default camera we can use to avoid the user's camera messing up the position too.

It would be great if we could add some unit tests so we can make sure it works in a few scenarios, and stays working for future changes. Maybe we could have some tests that:

  • applies some kind of transformation
  • draws a rectangle
  • applies the invert filter
  • loads pixels
  • checks that the colors are correct where the rectangle should be, and maybe in one spot where it isn't.

For the transformations to test, we could have a test case for:

  • No transformation
  • A translation via translate(...)
  • A translation via making a camera and calling cam.move(...)

@inaridarkfox4231
Copy link
Contributor Author

inaridarkfox4231 commented Oct 31, 2023

Also, it doesn't seem to support p5.Framebuffer (it might not be possible in the first place...)
filter_FBO

let fb;

function setup() {
  createCanvas(400, 400, WEBGL);
  
  fb = createFramebuffer({w:width, h:height});
}
function draw(){

  fb.begin();
  orbitControl();
  background(0);
  lights();
  fill(255,0,0);
  specularMaterial(128);
  noStroke();
  torus(80, 20, 48);
  //filter(INVERT);
  fb.end();

  clear();
  image(fb.color, -200, -200);
  filter(INVERT);
}
2023-10-31.22-58-56.mp4

Maybe I'm applying it wrong, or maybe I shouldn't use it this way.
It may also be resolved automatically if other issues such as transformation are resolved.
So I can't make a judgment on this. I will just state the results.

@davepagurek
Copy link
Contributor

I think the framebuffer one is solvable but would mean not applying filters on a separate graphic, and instead using another framebuffer in the same WebGL context. That's something we probably want to look into anyway for filters on WebGL canvases as it'll be faster than using a graphic. Feel free to open an issue for that too if you're interested! Otherwise I'll also get around to filing one at some point.

@inaridarkfox4231
Copy link
Contributor Author

I understood. I'm not familiar with p5.Framebuffer, so I'll leave this up to you.

@inaridarkfox4231
Copy link
Contributor Author

I checked several pull requests related to the development of the filter() specification. I got the impression that the situation to which it would be applied was fixed, and it was just a matter of matching the appearance. However, since image() is a function that draws the board, the effects of transform and blend cannot be avoided. I think that should have been considered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants