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

[compositing-2] 'lighter' vs 'plus-lighter' #446

Open
jakearchibald opened this issue Nov 29, 2021 · 16 comments
Open

[compositing-2] 'lighter' vs 'plus-lighter' #446

jakearchibald opened this issue Nov 29, 2021 · 16 comments

Comments

@jakearchibald
Copy link
Contributor

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

The difference between lighter and plus-lighter is that plus-lighter caps to 1. However, I can't find any cases where lighter allows values to go above 1. Here's a couple of canvases that I'd expect to be different if values were allowed to go above 1 https://static-misc-3.glitch.me/composite-test/cap.html - in this case both the red channel and alpha channel would go above 1.

plus-lighter and plus-darker were added when the compositing-2 doc was added 10f0d3d. I can't find any discussion of these, but I guess there must have been. @cabanier, @dbaron do either of you know the history here?

I wonder if it would make sense to specify that all blend and compositing modes are clamped to 0-1. Then, remove plus-lighter from the spec, and rename plus-darker to darker and remove the clamping (since it'd be covered by the overall clamping.

@cabanier
Copy link
Member

plus-lighter and plus-darker were added when the compositing-2 doc was added 10f0d3d. I can't find any discussion of these, but I guess there must have been. @cabanier, @dbaron do either of you know the history here?

This was requested a long time ago by @grorg : https://lists.w3.org/Archives/Public/public-fx/2015JanMar/0021.html

I wonder if it would make sense to specify that all blend and compositing modes are clamped to 0-1. Then, remove plus-lighter from the spec, and rename plus-darker to darker and remove the clamping (since it'd be covered by the overall clamping.

It makes sense to clamp the alpha to 1. I can't think of a reason how it could ever exceed that.
The color should not be clamped though as that will break certain effects where over-range colors are used.

@jakearchibald
Copy link
Contributor Author

This was requested a long time ago by @grorg : https://lists.w3.org/Archives/Public/public-fx/2015JanMar/0021.html

Ohhh thanks for finding that! @grorg, do you think we need both lighter and plus-lighter? Could we just have lighter and darker and have them both clamp.

It makes sense to clamp the alpha to 1. I can't think of a reason how it could ever exceed that.

Yeah, otherwise it gets weird when going between premultiplied and the other thing.

certain effects

Can a web API do that? Should I be seeing a difference in https://static-misc-3.glitch.me/composite-test/cap.html? If not, can you give me an example that shows it?

@cabanier
Copy link
Member

certain effects

Can a web API do that? Should I be seeing a difference in https://static-misc-3.glitch.me/composite-test/cap.html? If not, can you give me an example that shows it?

With HDR support, web APIs should be able to use it. For instance, an author could use plus to do a dissolve between 2 bright lights.
I remember asking the same question to the CSS group and they said it was valid for a color to be over 1. Looking at the css color spec, it seems that they updated the language around color but IMO they made it more confusing.

If we're going to clamp the color, it certainly shouldn't be 1 though since I though that not all color spaces go between 0 and 1.

@jakearchibald
Copy link
Contributor Author

jakearchibald commented Nov 29, 2021

With HDR support, web APIs should be able to use it.

By HDR you mean an image that has colours outside the colour space rather than, say, rec2020? I thought it was rec2020 it'd still be 0-1, but in another space.

@svgeesus
Copy link
Contributor

svgeesus commented Nov 29, 2021

By HDR you mean an image that has colours outside the colour space rather than, say, rec2020? I thought it was rec2020 it'd still be 0-1, but in another space.

If you convert HDR rec-2100 to rec-2020 (which uses the same primaries and whitepoint) you will get some colors with slightly negative, or greater than unity, components.

For example color(rec2100pq 0.71 0.78 0.67) would be color(rec2020 1.796 2.431 1.505) all the components are over 1.

I remember asking the same question to the CSS group and they said it was valid for a color to be over 1.

It is:

An out of gamut color has component values less than 0 or 0%, or greater than 1 or 100%. These are not invalid; instead, for display, they are gamut-mapped using a relative colorimetric intent which brings the values within the range 0/0% to 1/100% at computed-value time.

(Bearing in mind that CSS Color 4 is SDR-only, but designed to allow HDR to be built on top of it. Which is why all colors are defined over the extended range)

@jakearchibald
Copy link
Contributor Author

Ok. So is it justified to have lighter and plus-lighter where the only difference is that one is clamped?

For the cross-fading use-case we can use either.

It still isn't clear to me if https://static-misc-3.glitch.me/composite-test/cap.html is behaving correctly across browsers or not. @svgeesus what do you think?

@jakearchibald
Copy link
Contributor Author

Wait, maybe lighter is the correct choice for the cross-fading case, because clamping to 1 messes with cases where we're cross-fading between two colours that are deliberately outside of the specified gamut.

@cabanier
Copy link
Member

Wait, maybe lighter is the correct choice for the cross-fading case, because clamping to 1 messes with cases where we're cross-fading between two colours that are deliberately outside of the specified gamut.

Yes.
Thinking about this some more, the clamping seems separate from the compositing.
In the normal case, you would want the color to be clamped to their range after the composite but for special effects, you might want to skip that.

@ccameron-chromium
Copy link

Over in this issue, a very similar issue came up, and at least with respect to RGB (ignoring A for the moment), the general idea is that color values shouldn't be clamped, and should be allowed to express colors of any gamut. The compositor will, at the end, clamp the colors to the gamut of the display, and to the SDR range.

With respect to HDR, I do feel that the best thing to do is to specify "we will clamp to SDR unless something is explicitly specified using some yet-to-be-defined API".

To open the HDR bikeshed doors a bit ... my sense is that we will eventually want to add a spec that allows an individual element to explicitly enable HDR for-just-that-element. When enabling HDR, it can specify what kind of HDR is desired (just-extended-values, or treat-as-HLG, or treat-as-extended-with-metadata-sort-of-like-PQ). This proposal discusses adding HDR to canvas elements. This is also similar to specifying a "working interpolation space" for an element. (This issue discusses whether or not that "working pixel buffer space" should be independent of the "HDR type of space for compositing the element" but ... that's a whole nother bike shed). The status of that spec is "we need to write a prototype so people can feel their way around what is best". To return to the issue at hand, saying "clamp to SDR and the device's gamut at the end of the pipeline" is compatible with all of that.

@cabanier
Copy link
Member

Over in this issue, a very similar issue came up, and at least with respect to RGB (ignoring A for the moment), the general idea is that color values shouldn't be clamped, and should be allowed to express colors of any gamut. The compositor will, at the end, clamp the colors to the gamut of the display, and to the SDR range.

For "regular" drawing, color should be clamped to a valid range. Going outside that (ie with ICC color) will no longer result in accurate color rendering.
Also, the compositor doesn't clamp to the gamut. It should render in (or receive pixels of) the output colorspace.

With respect to HDR, I do feel that the best thing to do is to specify "we will clamp to SDR unless something is explicitly specified using some yet-to-be-defined API".

I think that is reasonable. We would have to define what to clamp to though.

To open the HDR bikeshed doors a bit ... my sense is that we will eventually want to add a spec that allows an individual element to explicitly enable HDR for-just-that-element. When enabling HDR, it can specify what kind of HDR is desired (just-extended-values, or treat-as-HLG, or treat-as-extended-with-metadata-sort-of-like-PQ).

I don't quite understand how that would work with a single element. You always want to render a group of graphics to a single colorspace.

This proposal discusses adding HDR to canvas elements. This is also similar to specifying a "working interpolation space" for an element. (This issue discusses whether or not that "working pixel buffer space" should be independent of the "HDR type of space for compositing the element" but ... that's a whole nother bike shed). The status of that spec is "we need to write a prototype so people can feel their way around what is best".

Adobe applications have the "working colorspace" which is the colorspace that compositing takes place in and the "target colorspace" which is the one of the device. Typically they are the same but some workflows and placed content (ie PDF) allow them to be different.
In the case of the web, iframes and canvas would be similar.

@jakearchibald
Copy link
Contributor Author

@grorg would you be happy with deprecating plus-lighter and plus-darker by aliasing them to lighter and darker? It seems like Safari supports darker even though it isn't in the spec.

@jakearchibald
Copy link
Contributor Author

jakearchibald commented Dec 3, 2021

It still isn't clear to me when the colours would be clamped to the gamut.

@ccameron-chromium

The compositor will, at the end, clamp the colors to the gamut of the display

When is "the end"? For example:

const ctx = canvas.getContext('2d');

ctx.fillStyle = 'rgb(100%, 0%, 0%)';
ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = 'rgb(100%, 100%, 0%)';
ctx.globalCompositeOperation = 'lighter';
ctx.fillRect(0, 0, canvas.width, canvas.height);

ctx.fillStyle = 'rgb(50%, 50%, 0%)';
ctx.globalCompositeOperation = 'multiply';
ctx.fillRect(0, 0, canvas.width, canvas.height);

Is the multiply destination rgb(200%, 100%, 0%) (unclamped after 'lighter') or rgb(100%, 100%, 0%) (clamped after 'lighter')?

Would the result be different if the compositing was done with mix-blend-mode or background-blend-mode?

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

FYI, fiddling with the test that is being added in web-platform-tests/wpt#41713 shows that all of Chromium, Gecko, and WebKit appear to implement lighter using the spec formula for plus-lighter rather than the formula given for lighter. (Though I admit that that test is using sRGB as the canvas color space -- perhaps I should test a bit using other colorSpace options?)

@dbaron dbaron added the Agenda+ label Aug 30, 2023
@dbaron
Copy link
Member

dbaron commented Aug 30, 2023

That said, the test is testing values that have to be clamped, so I suppose there's no way the spec formula would result in passing. The question is really whether the test should have separately clamped the values after the compositing formula.

I guess the question is really whether the difference in clamping between the two formulas is meaningful when we start talking about other color spaces. If there is a difference, then which one is right? And if there isn't a difference, which one is a clearer way to specify it?

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
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}
@css-meeting-bot
Copy link
Member

The CSS Working Group just discussed [compositing-2] 'lighter' vs 'plus-lighter', and agreed to the following:

  • RESOLVED: make lighter defined the way plus-lighter is now defined, pending checking some additional tests that might show differences
The full IRC log of that discussion <flackr> dbaron: the compositing spec has a list of blend modes, one is lighter, one is plus-lighter. The only diff between them is that lighter does not clamp the color values to the [0, 1] range. It allows the output color to be greater than 1. It's the only compositing operator that does this.
<Rossen_> q?
<flackr> dbaron: I.e. only one that can take two colors in [0, 1] range and produce values outside of this range.
<flackr> dbaron: it's not clear if this is detectable?
<flackr> dbaron: in theory there's some color space things that might be able to test this
<flackr> dbaron: it would be useful to have people aware of the color stuff weigh in on what is the right thing here
<flackr> dbaron: there's some weigh in but it would be useful to have clear opinion
<flackr> dbaron: my inclination is lighter and plus-lighter should be the same
<flackr> dbaron: lighter should be what plus-lighter is
<flackr> florian: and get rid of plus-lighter?
<bkardell_> q+
<flackr> dbaron: yes
<Rossen_> ack bkardell_
<florian> s/dbaron: yes/dbaron: not sure it would be compatible with existing content to do so
<flackr> bkardell_: on the issue, i saw that checking the 3 impls they're using the spec formula for plus-lighter, though may need testing using other color space options...
<flackr> dbaron: maybe we should tentatively resolve to make them the same unless there's a reason not to
<flackr> bkardell_: if impls are the same seems like a good idea
<flackr> dbaron: they're only the same in so far as i've tested so far
<flackr> Rossen_: should we accept the proposal - make them the same?
<dbaron> Proposed resolution: make lighter defined the way plus-lighter is now defined, pending checking some additional tests that might show differences
<flackr> RESOLVED: make lighter defined the way plus-lighter is now defined, pending checking some additional tests that might show differences

@jakearchibald
Copy link
Contributor Author

In a perfect world, we'd only have lighter, and plus-lighter wouldn't be a thing. The reason we pushed for plus-lighter to be added to the spec is because Safari had already shipped it for years, so it seemed too late to have a naming discussion.

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