blendMode to reduce opacity?

Hi! I have a circle on a PGraphics. I want reduce the opacity of parts of it. Imagine painting with your mouse on the PGraphics and instead of adding paint, it becomes more transparent under the mouse.

By using blendMode(REPLACE); I can make it fully transparent, but is it possible to apply say 50% transparency?

PGraphics pg;

void setup() {
  size(300, 300, P2D);
  pg = createGraphics(width, height, P2D);
  pg.beginDraw();
  pg.background(255, 0);
  
  // draw white circle
  pg.noStroke(); 
  pg.ellipse(width/2, height/2, 200, 200);
  
  // bite the circle, reduce opacity
  pg.blendMode(REPLACE);
  pg.fill(255, 0);
  pg.ellipse(width/3, height/3, 200, 200);
  
  pg.endDraw();  
}

void draw() {
  background(#DDDDDD);
  line(0, 0, width, height);
  image(pg, 0, 0);
}

produces

2018-12-17-152638_300x300_scrot

I try reducing opacity like this

  // bite the circle, reduce opacity
  pg.blendMode(SUBTRACT);
  pg.fill(0, 100);
  pg.ellipse(width/3, height/3, 200, 200);

but this is what I get:
2018-12-17-152858_300x300_scrot
The opacity of the white circle is not reduced, and for some reason the transparent area becomes partially opaque.

MULTIPLY gives me a similar result, so it seems like the alpha is not multiplied.

I know how to do it with a shader, but I was wondering if it’s possible to achieve with blendMode? Is this related to those pre-multiplied alpha issues?

1 Like

See my message in the thread at Low framerate when my line is fading away? (which you were also involved in! :wink: ) It’s doable but you need to access PGL and set the blend functions back to the old implementation of MULTIPLY. eg.

p.blendMode(MULTIPLY); // just make sure Processing does all the other blendMode related things
((PGraphicsOpenGL)p).pgl.blendFunc(PGL.ZERO, PGL.SRC_COLOR);
3 Likes

Nice! Thank you :slight_smile: You’r the blend master :stuck_out_tongue:

  // bite the circle, reduce opacity
  pg.blendMode(MULTIPLY); // just make sure Processing does all the other blendMode related things
  ((PGraphicsOpenGL)pg).pgl.blendFunc(PGL.ZERO, PGL.SRC_COLOR);
  pg.fill(255, 150);
  pg.ellipse(width/3, height/3, 200, 200);

2018-12-17-161523_300x300_scrot

Beautiful :slight_smile:

2 Likes

Haha, thanks! :blush: Been doing this blend stuff for a long time, including hacking around Processing’s shortcomings in this area. In fact, one key difference in PraxisLIVE is correctly functioning blend modes and pre-multiplied alpha (former requires latter). Tried to get it fixed upstream (see eg. https://github.com/processing/processing/issues/3391 ) Current MULTIPLY is neither a correctly functioning (ie. Photoshop-like) multiply, nor the also useful masking multiply that you needed.

What are the default args for blendMode(MULTIPLY) ?

GitHub search gives me only two mentions of blendFunc.

Update: must be a GitHub search bug, a local search gives me the answer

$ ag blendFunc -C 5

opengl/PGraphicsOpenGL.java
...
6290-    } else if (blendMode == MULTIPLY) {
6291-      if (blendEqSupported) {
6292-        pgl.blendEquationSeparate(PGL.FUNC_ADD,
6293-                                  PGL.FUNC_ADD);
6294-      }
6295:      pgl.blendFuncSeparate(PGL.ZERO, PGL.SRC_COLOR,
6296-                            PGL.ONE,  PGL.ONE);
6297-
6298-    } else if (blendMode == SCREEN) {

Update 2: In GitHub

Only files smaller than 384 KB are searchable.

2 Likes

1545063221869t

This is where I need to spray some transparency, to avoid it becoming too messy :slight_smile: There are still some glitches, but it’s better than before.

4 Likes

Well, you found it eventually. For a proper Photoshop-style multiply it should be (if Processing also supported pre-multiplied alpha) -

pgl.blendFunc(PGL.DST_COLOR, PGL.ONE_MINUS_SRC_ALPHA);

This correctly accounts for alpha in the source - ie. transparent areas should cause no effect. Of course, not what you need for this! Code from here

Incidentally, on blend modes, the slides I linked to in the issue above are worth a read through - https://www.slideshare.net/Mark_Kilgard/blend-modes-for-opengl

(somehow never come across ag before - thanks! Definitely my search tool of choice now! :smile: )

2 Likes

If anyone needs to use blendFunc() I found this great page where you can experiment with the values until you get the effect you want:

https://andersriggelsen.dk/glblendfunc.php

Also half way down this page https://learnopengl.com/Advanced-OpenGL/Blending the math is explained.