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

[css-compositing-2] Remove or fix definition of plus-darker #447

Open
jakearchibald opened this issue Jan 12, 2022 · 6 comments
Open

[css-compositing-2] Remove or fix definition of plus-darker #447

jakearchibald opened this issue Jan 12, 2022 · 6 comments

Comments

@jakearchibald
Copy link
Contributor

jakearchibald commented Jan 12, 2022

https://drafts.fxtf.org/compositing/#porterduffcompositingoperators_plus_darker

The definition here seems plain wrong. For instance:

co = max(0, 1 - αs x Cs + 1 - αb x Cb)
// Assuming
// αs = 1
// αb = 1
// Cs = 0.5
// Cb = 0
co = max(0, 1 - 1 x 0.5 + 1 - 1 x 0)
co = max(0, 1.5)
co = 1.5

max(0, x) is used, which suggests x will be a maximum of 1, but the definition produces values 0-2 (assuming pixel values are 0-1).

Safari supports the plus-darker value for mix-blend-mode.

The definition in Apple's docs matches the spec, so it's incorrect for the same reasons. The implementation is closed source, so I can't check how it actually works.

It seems like, on WebKit Linux (via cairo), plus-darker is an alias of darken, which doesn't match what I see in Safari. I might not be interpreting the source correctly.

We have not heard any use-cases for plus-darker, although maybe that will become clearer with correct documentation.

@pacocoursey
Copy link

@jakearchibald Would you consider advocating for plus-darker to be brought back into the spec and/or implementation? It's extremely useful for increased vibrancy of translucent materials, which are becoming more common on the web thanks to the power of filters and blend modes. Apple uses both plus-lighter and plus-filter blend modes across all of their operating systems, iOS in particular.

Here's an example (taken directly from Apple's macOS Sketch Design Template) where plus-darker on WebKit boosts vibrancy and legibility:

MmkqKuKg@2x

(codepen)

It also seems silly to only implement plus-lighter without its opposite!

@dbaron
Copy link
Member

dbaron commented Mar 30, 2023

The first problem here is that nobody's published a formula for what Apple's plus-darker is that we believe is correct.

For what it's worth, if I were to try to make up a plus-darker formula that was the opposite of plus-lighter but darkening, I think I'd probably write:

Fa = 1; Fb = 1;
co = max(0, 1 - αs x Cs - αb x Cb);
αo = min(1, αs + αb);

I have not tested to see if this does anything close to reasonable.

(On a related topic, the only difference between lighter and plus-lighter appears to be the clamping to the [0, 1] range.)

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 30, 2023
This test tests for the current spec, but it is also designed so that we
can use it to make progress on changing the spec in
w3c/fxtf-drafts#446 and
w3c/fxtf-drafts#447 .

Change-Id: If0f321a0fef7279fabfba9c613556371f42f9875
Bug: 1477259
@dbaron
Copy link
Member

dbaron commented Aug 30, 2023

I wrote a test in web-platform-tests/wpt#41713 that tests the composite modes in canvas. It turns out my test objected to the formula in #447 (comment) because it wasn't producing properly premultiplied colors: there were cases where the color result was greater than the alpha result, which isn't allowed.

However, my formula was sort of close; it appears (based on fiddling with my test) that what Safari implements for plus-darker is:

co = min(1, αs + αb) - min(1, αs x (1 - Cs) + αb x (1 - Cb));
αo = min(1, αs + αb);

(It's possible there's a simpler way to write this, but that's the expression I figured out that leads to Safari passing the test for plus-darker.)

@dbaron dbaron changed the title [css-compositing-2] Remove plus-darker [css-compositing-2] Remove or fix definition of plus-darker Aug 30, 2023
@dbaron dbaron added the Agenda+ label Aug 30, 2023
aarongable pushed a commit to chromium/chromium that referenced this issue Aug 30, 2023
This test tests for the current spec, but it is also designed so that we
can use it to make progress on changing the spec in
w3c/fxtf-drafts#446 and
w3c/fxtf-drafts#447 .

Change-Id: If0f321a0fef7279fabfba9c613556371f42f9875
Bug: 1477259
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4827182
Auto-Submit: David Baron <dbaron@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1190349}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 30, 2023
This test tests for the current spec, but it is also designed so that we
can use it to make progress on changing the spec in
w3c/fxtf-drafts#446 and
w3c/fxtf-drafts#447 .

Change-Id: If0f321a0fef7279fabfba9c613556371f42f9875
Bug: 1477259
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4827182
Auto-Submit: David Baron <dbaron@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1190349}
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Aug 30, 2023
This test tests for the current spec, but it is also designed so that we
can use it to make progress on changing the spec in
w3c/fxtf-drafts#446 and
w3c/fxtf-drafts#447 .

Change-Id: If0f321a0fef7279fabfba9c613556371f42f9875
Bug: 1477259
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4827182
Auto-Submit: David Baron <dbaron@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1190349}
moz-v2v-gh pushed a commit to mozilla/gecko-dev that referenced this issue Sep 13, 2023
…s., a=testonly

Automatic update from web-platform-tests
Add canvas-based test for composite modes.

This test tests for the current spec, but it is also designed so that we
can use it to make progress on changing the spec in
w3c/fxtf-drafts#446 and
w3c/fxtf-drafts#447 .

Change-Id: If0f321a0fef7279fabfba9c613556371f42f9875
Bug: 1477259
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4827182
Auto-Submit: David Baron <dbaron@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1190349}

--

wpt-commits: 808ba394dd5f6a6904521f4a5f810fac8e70a8e3
wpt-pr: 41713
vinnydiehl pushed a commit to vinnydiehl/mozilla-unified that referenced this issue Sep 14, 2023
…s., a=testonly

Automatic update from web-platform-tests
Add canvas-based test for composite modes.

This test tests for the current spec, but it is also designed so that we
can use it to make progress on changing the spec in
w3c/fxtf-drafts#446 and
w3c/fxtf-drafts#447 .

Change-Id: If0f321a0fef7279fabfba9c613556371f42f9875
Bug: 1477259
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4827182
Auto-Submit: David Baron <dbaron@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1190349}

--

wpt-commits: 808ba394dd5f6a6904521f4a5f810fac8e70a8e3
wpt-pr: 41713
@smfr
Copy link

smfr commented Oct 31, 2023

Comments in Apple source code say:

//        /* R = MAX(0, 1 - ((1 - D) + (1 - S))). {R, S and D are premultiplied
//           so actually R = MAX(0, (Da+Sa) - ((Da - D) + (Sa - S))) } */
//                         = MAX(0, Da + Sa - Da + D - Sa + S
//                         = MAX(0, D + S)

Where R=result, D=destination, S=source as premultiplied values.

@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [css-compositing-2] Remove or fix definition of plus-darker, and agreed to the following:

  • RESOLVED: define plus-darker based on research results in the issue and raise issue to deal with max/min in various cases
The full IRC log of that discussion <bramus> astearns: there was a q here on what was actually implemented, and we got some feedback from impl. is that enough to know what to do?
<bramus> vmpstr: generally we want to align with webkit here in the spec
<bramus> vmpstr: and then implement from thereon
<bramus> dbaron: yes, it seems like the results I got from testing with safari and what apple (simon) says agrees, so we should put that in the spec
<bramus> … one side comment is that i am interest in feedback from color experts on how this is supposed to work outside of srgb
<chris> q+
<bramus> … some formulas have max fns in them in interesting ways that assume the color space runs from 0 to 1 (I think)
<bramus> … would be good to get that written down by experts
<astearns> ack chris
<bramus> … so this is a call for interested folks to look at it
<bramus> chris: I can give a brief explanation
<bramus> astearns: or we could resolve to define this for srgb and open issue for the rest (if that is needed)
<bramus> chris: sgtm
<bramus> … and that was a good question dbaron
<bramus> dbaron: (agrees)
<bramus> astearns: would the possible improvmenets need to be added to ???
<bramus> dbaron: not all, maybe 3 or 4
<bramus> astearns: PROPOSED RESOLUTION: define plus-darker based on research results in the issue and raise issue to deal with max/min in various cases
<bramus> RESOLVED: define plus-darker based on research results in the issue and raise issue to deal with max/min in various cases

Lightning00Blade pushed a commit to Lightning00Blade/wpt that referenced this issue Dec 11, 2023
This test tests for the current spec, but it is also designed so that we
can use it to make progress on changing the spec in
w3c/fxtf-drafts#446 and
w3c/fxtf-drafts#447 .

Change-Id: If0f321a0fef7279fabfba9c613556371f42f9875
Bug: 1477259
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4827182
Auto-Submit: David Baron <dbaron@chromium.org>
Reviewed-by: Vladimir Levin <vmpstr@chromium.org>
Commit-Queue: Vladimir Levin <vmpstr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1190349}
@magcius
Copy link

magcius commented Dec 26, 2023

The logic in here is hard to follow.

The definition in Apple's docs matches the spec, so it's incorrect for the same reasons. The implementation is closed source, so I can't check how it actually works.

That's correct, except I think this is a typo when it was integrated into AppKit. The original blend mode can be found in CoreGraphics with an important twist: 1 - ((1 - S) + (1 - D)). This 1 - flips everything on its head, and simplifies to S + D - 1. It's additive, but there's an extra -1 tossed into one of the sides for good measure. That doesn't give you the generalized formula for blending with alpha, though.

However, my formula was sort of close; it appears (based on fiddling with my test) that what Safari implements for plus-darker is:

co = min(1, αs + αb) - min(1, αs x (1 - Cs) + αb x (1 - Cb));
αo = min(1, αs + αb);

I don't have an easy system to test CoreCG with, so I'm going to assume this is the actual formula. min(1, ...) on the left here is loadbearing, perhaps unintentionally. It's what's stopping this from becoming the same as plus-lighter. Normally, αs + αb would add to 2.0 for two opaque images, but since the min caps it to 1 it effectively adds the - 1 bias on the right-hand side. Note, however, that if you have two images with alphas that don't add to more than 1, it becomes the same as plus-lighter.

There are some other formulas that you could come up with, like S + D - Sa*Da that I think would try to take this into account, but I can't think of any correct way to blend darker that doesn't make compromises somewhere.

Comments in Apple source code say:

//        /* R = MAX(0, 1 - ((1 - D) + (1 - S))). {R, S and D are premultiplied
//           so actually R = MAX(0, (Da+Sa) - ((Da - D) + (Sa - S))) } */
//                         = MAX(0, Da + Sa - Da + D - Sa + S
//                         = MAX(0, D + S)

This is clearly incorrect, as should be evidenced by the resulting formula being effectively the same as plus-lighter (additive blending). You can't swap out the 1 for both "Da+Sa" and "Da"/"Sa" without a clamp.

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

No branches or pull requests

6 participants