Skip to content

Conversation

@othp
Copy link

@othp othp commented Jun 17, 2014

This changes the opengl multiply blend mode implementation so the output matches the default renderer.

Consider:

void setup() {
  size(500,500);
  background(255);
  noStroke();
}

void draw() {
  background(255);
  blendMode(BLEND);
  fill(#3D59AB);
  ellipse(width*0.3, height*0.5, width*0.5, height*0.5);
  blendMode(MULTIPLY);
  fill(#FFD700);
  ellipse(width*0.7, height*0.5, width*0.5, height*0.5);
}

Result:
output

Change the size method to use P2D instead and you get:
p2d_output

This change makes the P2D renderer output the same as the JAVA2D renderer.

@codeanticode codeanticode self-assigned this Jun 18, 2014
@neilcsmith-net
Copy link

That is the correct OpenGL blending for Multiply, but only for colours with premultiplied alpha. The results with an opaque fill or opaque image will be correct, but anything less than opaque will veer towards adding brightness rather than veering towards having no effect. AFAIK there is no blend settings in OpenGL that will do Multiply correctly with non-premultiplied alpha like in Processing.

@benfry
Copy link
Contributor

benfry commented Jul 30, 2014

@codeanticode before 2.0, weren't we using ONE_MINUS_SRC_ALPHA?

@benfry
Copy link
Contributor

benfry commented Nov 4, 2014

@JakubValtar @codeanticode are we set on this via f43046a ?

@JakubValtar
Copy link
Contributor

@benfry @codeanticode Yes, this is no longer relevant.

@neilcsmith-net
Copy link

That new Multiply code is still broken though, at least for non-opaque sources. Perhaps the documentation should mention that? I use the OP's suggested settings in Praxis LIVE, but that uses a subclassed PGraphicsOpenGL that uses pre-multiplied textures. That may be a drastic solution just for this issue :-) Mind you as an alternative colour option that would be great, and happy to contribute back anything useful.

@JakubValtar
Copy link
Contributor

I feel your pain. What would you propose as a reasonable default MULTIPLY for majority of users?

The new MULTIPLY just multiplies the colors and adds alphas together. We have modes which support alpha – REPLACE, BLEND, ADD, SUBTRACT. There is no compromise, the result is correct and what you would expect. Other modes like LIGHTEST, DARKEST, EXCLUSION, MULTIPLY and SCREEN ignore alpha because OpenGL can't do this. Is there a reason why MULTIPLY should have an exception and try to work with alpha even if there is no good way to do it and have reliable results for all possible colors and alphas? I think this is the most intuitive and consistent solution. (full pull request)

Please also note that Processing does not claim to support pre-multiplied alpha. It would be great to have it in the future, but right now you do this at your own risk.

I'm sorry if I sound angry, I had a long day and I'm just trying to explain the reason why I did new multiply this way. I understand your point and would be happy to hear your thoughts.

If you need your own mode, you can use PGL, so I think advanced users can still have their cake:

void draw() {
  PGL pgl = beginPGL();
  pgl.blendEquation(PGL.FUNC_ADD);
  pgl.blendFunc(PGL.DST_COLOR, PGL.ONE_MINUS_SRC_ALPHA);

  // all your drawing
  rect(...);
  ellipse(...);

  flush();
  endPGL();
}

Edit: Sure, documentation needs to mention the changes.

@neilcsmith-net
Copy link

On 4 November 2014 18:25, Jakub Valtar notifications@github.com wrote:

I feel your pain. What would you proporse as a reasonable default MULTIPLY for majority of users?

Without major refactoring, this, as long as it's properly documented
in which situations it can work - in some ways this issue should
probably be a won't fix!

Other modes like LIGHTEST, DARKEST, EXCLUSION, MULTIPLY and SCREEN ignore alpha because OpenGL can't do this.

Unless the surfaces are pre-multiplied (not sure on all). Note that
I'm not talking about changing the external API, just how textures are
stored, though this would have an effect on shaders. It would also be
a major decision.

Please also note that Processing does not claim to support pre-multiplied alpha. It would be great to have it in the future, but right now you do this at your own risk.

If you'd seen how much I've hacked the renderer to get it to work in
my context! ;-)

I'm sorry if I sound angry, I had a long day and just try to explain the reason why I did new multiply this way. I understand your point and would be happy to hear your thoughts.

If you need your own mode, you can still use PGL, so I think advanced users can still have their cake:
...
pgl.blendFunc(PGL.DST_COLOR, PGL.ONE_MINUS_SRC_ALPHA);

Sorry if I made you sound angry! ;-) A lot of blending issues in
Processing GL are caused by the decision not to go with pre-multiplied
alpha. You seem to have done a great job fixing the ones that can be
fixed. Unfortunately, that alternative blending for Multiply is as
equally broken without pre-multiplied alpha as your's!

Best wishes, Neil

Neil C Smith
Artist : Technologist : Adviser
http://neilcsmith.net

Praxis LIVE - open-source intermedia development - www.praxislive.org
Digital Prisoners - interactive spaces and projections -
www.digitalprisoners.co.uk

@benfry
Copy link
Contributor

benfry commented Nov 4, 2014

Folks, I'm gonna close this one since the original issue is sorted out.

However, it sounds like it might be a good idea to file a new issue around "how might we implement premultiplied alpha" for a future release?

@benfry benfry closed this Nov 4, 2014
@JakubValtar
Copy link
Contributor

Agreed.

@github-actions
Copy link

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 15, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants