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

Minimal HDR Canvas proposal #95

Merged
merged 18 commits into from
May 2, 2023
Merged

Minimal HDR Canvas proposal #95

merged 18 commits into from
May 2, 2023

Conversation

palemieux
Copy link
Contributor

@palemieux palemieux commented Feb 24, 2023

Refactor the HDR Canvas proposal to a minimal baseline focused on today's HDR imagery and practice without precluding future optimizations and extensions.

Highlights:

  • add support for HLG and PQ color spaces, including explicit recommendations for:
    • tone-mapping from HLG and PQ to sRGB
    • mapping from sRGB to HLG and PQ
    • mapping between HLG and PQ
  • add support 16-bit floats bitmaps

hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
Copy link
Member

@chrisn chrisn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just reviewing today, so I added a few more comments

hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
@palemieux palemieux changed the title Simplification of the HDR Canvas proposal Minimal HDR Canvas proposal Mar 20, 2023
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
hdr_html_canvas_element.md Outdated Show resolved Hide resolved
@palemieux palemieux marked this pull request as draft March 20, 2023 16:45
@palemieux palemieux mentioned this pull request Mar 24, 2023
@palemieux palemieux marked this pull request as ready for review March 24, 2023 23:27
Copy link
Contributor

@svgeesus svgeesus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few minor comments

A color is said to be within a screen's extended range if, when that color is converted to the screen's native linear color space (using relative colorimetric intent), all of its color components are within the `[0, highDynamicRangeHeadroom]` interval.
When displaying content produced by a rendering context with `CanvasHighDynamicRangeMode` set to `'extended'`, all colors that are within the screen's extended range must be displayed without any clamping or roll-offs (neither in chrominance nor luminance).
A color is said to be within a screen's *extended* range if, when that color is converted to the screen's native linear color space
(using relative colorimetric intent), all of its color components are within the `[0, highDynamicRangeHeadroom]` interval. When
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That definition carefully excludes out of gamut colors, which would have some negative values, while leaving in-gamut HDR values. Nice.

A color is said to be within a screen's *extended* range if, when that color is converted to the screen's native linear color space
(using relative colorimetric intent), all of its color components are within the `[0, highDynamicRangeHeadroom]` interval. When
displaying content produced by a rendering context with `CanvasHighDynamicRangeMode` set to `'extended'`, all colors that are within
the screen's extended range must be displayed without any clamping or roll-offs (neither in chrominance nor luminance).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That precludes any soft rolloff or tonemapping. Is that intentional?


* Connection matrix: matrix to convert the [sRGB primaries](https://www.w3.org/TR/css-color-4/#valdef-color-srgb) to the primary colours specified in Rec. ITU-R BT.2100
In general, application should avoid conversions between color spaces and maintain imagery in its original color space: conversions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But canvas always converts on input from the specified colorspace to that of the canvas.

hdr_html_canvas_element.md Show resolved Hide resolved
_Note 1:_ As `rec2100-hlg` is a relative format, the brightness of the virtual monitor used for mathematical transforms can be chosen to be any level. In this transform it is chosen to be 302 cd/m2 so that the brightness of diffuse white matches the diffuse white of sRGB (80 cd/m2). Using the extended range gamma formula in footnote 2 of BT.2100, this also sets the HLG Inverse OOTF to be unity. The value 0.265 is calculated by taking the inverse OETF of 0.75, the `rec2100-hlg` diffuse white level.

_Note 2:_ See section 5.3 in ITU-R BT.2408-4 relating to negative transfer functions in format conversions.
1. Apply HLG EOTF to convert the non-linear `rec2100-hlg` Signal to linear Pseudo-Display Light with Lw = 302 cd/m2 - See Note 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: 302 should be 203

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are looking at an old version of the document.


_Output:_ Full-range non-linear floating-point `rec2100-hlg` pixel with black at 0.0 and diffuse white at 0.75. Values may exist outside the range 0.0 to 1.0.

_Process:_
1. Convert from `extended-linear-srgb` color space to `rec2100-hlg` color space

1. Convert from `extended-srgb-linear` color to `rec2100-hlg` color
2. Scale pixel values - See Note 1
3. Apply HLG Inverse EOTF to convert to HLG from Pseudo-Display Light with Lw = 302 cd/m2 - See Note 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again should be 203

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are looking at an old version of the document.

_Input:_ Full-range non-linear floating-point `extended-srgb` pixel with black at 0.0 and diffuse white at 1.0. Values may exist outside the range 0.0 to 1.0.

_Output:_ Full-range non-linear floating-point `rec2100-pq` pixel with black at 0.0 and diffuse white at ???. Values may exist outside the range 0.0 to 1.0.
_Note 1:_ As `rec2100-hlg` is a relative format, the brightness of the virtual monitor used for mathematical transforms can be chosen to be any level. In this transform it is chosen to be 302 cd/m2 so that the brightness of diffuse white matches the diffuse white of sRGB (80 cd/m2). Using the extended range gamma formula in footnote 2 of BT.2100, this also sets the HLG Inverse OOTF to be unity. The value 0.265 is calculated by taking the inverse OETF of 0.75, the `rec2100-hlg` diffuse white level.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

203


_Output:_ Full-range non-linear floating-point `extended-srgb` pixel with black at 0.0 and diffuse white at 1.0. Values may exist outside the range 0.0 to 1.0.
_Output:_ Full-range non-linear floating-point `rec2100-pq` pixel with black at 0.0 and diffuse white at ???. Values may exist outside the range 0.0 to 1.0.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What to say for ???
PQ diffuse white is at whatever the creative intent places it at, so maybe instead say peak small-area white (10,000 cd/m2) at 1.0?

Comment on lines 48 to 50
* drawing of visual elements that are related to an HDR video presentation, with
the expectation that the visual elements match the look of the HDR video
presentation.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: This third bullet talks about "HDR video presentation" even though HDR images are also covered by the proposal. I think we can drop the word "video" and simply refer to an "HDR presentation".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the following clearer?

drawing of visual elements that are related to an HDR presentation in a <video> element, with the expectation that the visual elements match the look of the <video> element presentation

'rec2100-hlg',
'rec2100-pq',
}
partial dictionary ImageDataSettings {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: For this and other partial definitions in the spec, please include all of the members of the type, with the new ones in bold. Saves me the trouble of hunting these down in the original spec.

'rec2100-pq',
}
partial dictionary ImageDataSettings {
ImageDataColorType colorType = "Uint8ClampedArray";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

colorType is assigned to Uint8ClampedArray but Uint8ClampedArray does not appear in the ImageDataColorType enum defined below.

Did you mean for this to be "unorm8"? Or did you mean for ImageDataColorType to have "Uint8ClampedArray" as a choice?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be "unorm". Thanks.

```idl
enum CanvasColorType {
"unorm8",
"float16",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see the highest bit depth of CanvasColorType is float16 but ImageDataColorType goes all the way to float32.

Is this a hedge against float16 not getting approved by the JS standards body? If not, seems like we should unify these or provide a use case for float32 in the spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a hedge against float16 not getting approved by the JS standards body?

I think it is saying that it is not an essential part of this spec, and that either would work -- at least initially. I do not like however the idea of a placeholder, so listing the two seemed the least terrible approach. What is your preference?

return [r4, g4, b4];
}
```idl
enum CanvasColorType {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't really call unorm8 and float16 "color types". I think "CanvasDataType" or "CanvasFormatType" would be a better name for this enum.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree. Done.


#### srgb-linear
Add a new CanvasColorMetadata dictionary:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will we help developers provide good values for the dataype and colorspace of the canvas? I originally thought the spec would have recommendations based on the metadata but the metadata is only available after the canvas is created.

Do we expect developers to first make an sacrificial canvas, see what metadata is returned, and then make the "real" canvas afterwards? Seems like the metadata should be available independent of an individual canvas instance.

In general, I think the spec should provide use cases for the metadata such as how the metadata guides what DOMString values to pass for 2D canvas colors. Without use cases, this is going to draw the ire of those who oppose any fingerprinting bits be exposed to web developers for informational purposes. I, personally, think we can make the case for having these but we need to be more clear why it is needed in the spec.

Copy link
Contributor Author

@palemieux palemieux Apr 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we definitely need more information -- similar to what is provided in the PNG 3ED spec: https://w3c.github.io/PNG-spec/#mDCv-chunk

There are two basic use cases:

  • the application receives the ST 2086 metadata, e.g. from metadata within the image file or from an API call. In this case, the application simply copies the information as in the CanvasSmpteSt2086Metadata structure
  • the application generates the ST 2086 metadata, in which case, there are best practices we should be able to point to

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See added prose

return 1 / scale;
}
```idl
// SMPTE ST 2086 color volume metadata.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please define what "SMPTE ST 2086" stands for somewhere in the spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed "ST 2086" from symbol names and added it as a reference in the prose.

}
```idl
// SMPTE ST 2086 color volume metadata.
dictionary CanvasSmpteSt2086Metadata {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does "SmpteSt2086" need to be part of the enum name? Is there some other metadata we plan to add in the future that needs its own dictionary? I think calling this CanvasMetadata should suffice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed "ST 2086" from symbol names and added it as a reference in the prose.

@michaeldsmith
Copy link

michaeldsmith commented Apr 19, 2023

The ST2094-10 Annex B method mentioned in the section "rec2100-pq to srgb"

image

needs parameters min/avg/max values.

The example code at https://www.sandflow.com/public/tone-mapping/index.html performs image analysis to determine the min/avg/max values. This is a great way to obtain the min/avg/max parameters for a single image.

I think that it should be suggested that the good results will come from obtaining the min/avg/max parameters via image analysis.

If image analysis is not performed, then the min/avg/max values need to be provided as parameters to 2094-10 Annex B another way. Default min and max values could come from ST2086 mastering display metadata min luminance and max luminance, default max value could come from MaxCLL metadata. The average will depend on if the scene is bright, average or dark. Using a default average value between 5-15 nits could be a good starting place.

@ccameron-chromium
Copy link
Collaborator

This removes the features related to rendering content in an SDR-relative, application-tone-mapped canvas (in particular, the extended mode, and the ScreenDetails parts.

Splitting these into two proposals is probably the right thing to do -- there is too much misunderstanding between the two worlds that both call themselves HDR.

I would also suggest separating the float16 support out from this proposal. It already has its own proposal here and lengthy-and-stalled discussion here.

A remaining core part of this proposal (with this PR applied) is a standardization of how to render PQ and HLG content on phone/tablet/laptop/desktop operating systems.

These operating systems parameterize their displays by two parameters: HDR headroom and color gamut (this encompasses of Windows, iOS, macOS, Android, and ChromeOS, including the built-into-a-TV variants). None of the existing standards address this problem (they have no concept of a time-varying HDR headroom, which is fundamental to all operating systems' implementations of HDR).

There is also this issue about standardizing how PQ and HLG images are to be rendered as HTMLImageElement.

@palemieux
Copy link
Contributor Author

I would also suggest separating the float16 support out from this proposal.

I do not think this is separable since HDR cannot exist in an 8-bit world, as described in the introduction.

there is too much misunderstanding between the two worlds that both call themselves HDR.

I do not see a misunderstanding.

HLG and PQ have been iterated for years and are used by all HDR TV and movie content. The web has become an important source of TV and movie consumption. It makes sense for the web platform to support them.

This does not preclude/conflict with other approaches, as far as I know.

@ccameron-chromium
Copy link
Collaborator

I would also suggest separating the float16 support out from this proposal.

I do not think this is separable since HDR cannot exist in an 8-bit world, as described in the introduction.

Changes to PredefinedColorSpace for HLG and PQ is valuable on its own, because PredefinedColorSpace is used by 2D canvas, ImageData, WebGL, and WebGPU.

There are some issues to be worked out for 2D canvas and ImageData with respect to float16 support, but WebGPU is already shipping support for it, and WebGL has a proposal that doesn't have any issues that I know of.

I wouldn't want us to block HLG and PQ support in WebGPU because of unrelated 2D canvas issues (which may take a long time to resolve).

I also don't think we should explicitly disallow 8-bit HDR (it's not unreasonable for HLG -- see these 8-bit JPEG HLG images).

@palemieux
Copy link
Contributor Author

I also don't think we should explicitly disallow 8-bit HDR

Have you read the article at https://ieeexplore.ieee.org/document/7514362 ? It lays out the fact that 8-bit is not even sufficient for sRGB at low luminance.

P.S.: The images show up HDR in my Chrome browser! :)

@palemieux
Copy link
Contributor Author

palemieux commented Apr 25, 2023

I wouldn't want us to block HLG and PQ support in WebGPU because of unrelated 2D canvas issues (which may take a long time to resolve).

I argue we should use HDR as a way to drive the resolution of these issues.

I am not disagreeing with you that there is an obstacle.

@kenrussell
Copy link
Collaborator

We could almost replace references to Float16Array with Float32Array and not only would no web developer notice, but also the references could be changed back to Float16Array once that has been shipped in browsers with no application impact. Since reads from Float16Array will immediately convert to 64-bit float (JavaScript's native number representation) and writes to Float16Array silently truncate from that representation, it will behave very similarly to how Float32Array does today.

However - since this might be contentious, getting this in to have a spec browsers can start implementing would be preferable in my opinion.

@svgeesus
Copy link
Contributor

I also don't think we should explicitly disallow 8-bit HDR

I disagree. Don't give people a footgun, and instead, use this to drive the higher-bit-depth canvas upgrade.

@palemieux palemieux merged commit 45bdcce into w3c:main May 2, 2023
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

Successfully merging this pull request may close these issues.

7 participants