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

Should webGL alpha default to false? #5552

Closed
aferriss opened this issue Jan 14, 2022 · 2 comments · Fixed by #5555
Closed

Should webGL alpha default to false? #5552

aferriss opened this issue Jan 14, 2022 · 2 comments · Fixed by #5555

Comments

@aferriss
Copy link
Contributor

I was looking into the issues described in #5451 & #5195 and testing out how alpha blending is working with webGL mode. I think that the current behavior is causing a fair amount of confusion and unexpected results.

Here is a red square on black with 50% opacity, two ways. The first is just using css with a red div on a black div. The second is p5's default drawing mode.

Example Sketch

 <style>
    body {
      background-color: blue;
    }

    #outer {
      background-color: black;
      width: 100px;
      height: 100px;
    }

    #inner {
      background-color: red;
      opacity: 0.5;
      width: 80px;
      height: 80px;
    }
  </style>

  <div id="outer">
    <div id="inner"></div>
  </div>
function setup() {
  createCanvas(100, 100);
}

function draw() {
  background(0, 0, 0, 255);
  fill(255, 0, 0, 128);
  rect(10, 10, 80, 80);
}

Screen Shot 2022-01-14 at 11 54 12 AM

So far everything looks good and like we'd expect.

However, if we change to webGL mode...
Screen Shot 2022-01-14 at 11 57 06 AM

You can see that the red color is blending with the blue background of the page, rather than the black of the canvas.

If I add in a setAttributes('alpha', false); then our blending works as expected again. Here's another example.

I feel like the current blending defaults cause unexpected results, and that setting it to false would cause the least amount of surprises. It also brings us in line with the output of the 2d renderer.

The only downside I currently can see with this change is that if you want a canvas with a transparent background, you'll now need to call setAttributes('alpha', true). However, I feel this is probably a more niche use case and this simple fix wouldn't be a burden to those people. Maybe we could also document that behavior somewhere as well.

If we agree, I'm happy to prepare a PR. It's just a single boolean change :)

@stalgiag Thoughts?

@stalgiag
Copy link
Contributor

Thanks for the clear research and write-up!

This is a bit of a point of flip-flopping on my part historically. 'alpha' was false by default until this PR which was in response to this issue.

The goal was to make the default behavior feel as close to the 2D renderer as possible, in that specific instance I was most concerned with what was expected from graphics objects. That said, I think I agree that alpha defaulting to false may prevent more unexpected behavior for more people.

@mkmori
Copy link

mkmori commented Mar 13, 2022

I became aware of this issue and how it was resolved in researching my new/old issue: #5634

For what it's worth, (besides being late to the conversation!) I feel the fix implemented in 1.4.1 benefits a particular use of WEBGL as the primary drawing context, at the expense of other expected or discoverable behaviors, esp. all the cool things one can do with additional graphics buffers.

Meanwhile, the quirks/issues surrounding rendering of non-opaque geometry in WEBGL persist--tho' "root cause" solutions might be here: #5451 (comment), #5451 (comment)

Personally, I feel WEBGL rendering in p5js is a work in progress, but in the meantime, drawing to offscreen buffers, masking, compositing, etc., have been working pretty well in recent years....

My notes as of v1.4.1:

Main Canvas Bkgd Opacity = 100% Bkgd Opacity < 100%
P2D Composite P2D and/or WEBGL p5.Graphics for a variety of purposes. setAttributes('alpha', true); must be called on any WEBGL graphics with background opacity <100%. Transparency issues ("show thru") restricted to transparent geometry in WEBGL buffer. Composite p5.Graphics...and, for example, add p5js elements to a web page without a border or background. setAttributes('alpha', true); must be called on any WEBGL graphics with background opacity <100%. Transparency issues restricted to transparent geometry in WEBGL buffer, (and may be less apparent when main canvas background opacity is zero).
WEBGL Use 3D API in main draw(); loop directly. Defaulting main canvas alpha to false helps avoid WEBGL rendering issues.... (I think...the main context being WEBGL tends to preclude effective use of offscreen buffers as rendering layers, so maybe instead of defaulting to false, alpha could be switched to true or false based on clear(); and background(); calls on the main canvas...?) Add 3D objects to a web page w/o background (or with partially transparent background). myCanvas._pInst.setAttributes('alpha', true) must be called for this to work as expected, (and any additional WEBGL buffers would tend to require setAttributes('alpha', true);, too.)...but this is where some of the more objectionable "show thru" issues occur, as per #5451.

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.

3 participants