CINXE.COM
Canvas, WebGL, and WebGPU – W3C Workshop on Wide Color Gamut and High Dynamic Range for the Web
<!DOCTYPE html> <html lang=en> <head> <meta content="text/html; charset=utf-8" http-equiv=Content-Type> <title>Canvas, WebGL, and WebGPU – W3C Workshop on Wide Color Gamut and High Dynamic Range for the Web</title> <meta name=viewport content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="../fonts/iconmonstr-iconic-font.css"> <link rel=stylesheet href="https://unpkg.com/pdfjs-dist@2.8.335/web/pdf_viewer.css"> <link rel="stylesheet" href="/Graphics/Color/Workshop/style.css"> <style> /* Miscellaneous icons. Add something like class="picto im-info" to an element to prefix the element with the im-info icon from the iconmonstr-iconic font. */ .picto::before {font-family: iconmonstr-iconic-font; font-size-adjust: 1.0; /*line-height: 0.6;*/ font-style: normal; margin-right: 0.33em; vertical-align: middle; text-indent: 0; text-rendering: auto; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale} li.picto {list-style: none; padding-left: 0; margin-left: 0} /* class=button makes elements look like a button. */ .button, button {text-decoration: none; cursor: default; letter-spacing: normal; word-spacing: normal; display: inline-block; text-align: center; font: 400 100%/1.3 system-ui, Segoe UI, sans-serif; padding: 1px 8px 2px; padding: 1px 8px; margin: 0.1em; border-radius: 0.25em; background: hsla(204,0%,86%,1.0) padding-box; color: black; border: 1px outset hsla(204,0%,86%,1.0)} .button > *, button > * {margin-top: 0; margin-bottom: 0} .button.picto:empty, button.picto:empty {padding-right: 4px} /* Disabled buttons and button-like elements. */ .button[disabled], button[disabled] {border-style: inset; opacity: 0.6} /* class=buttons makes a row of three buttons. */ .buttons {display: flex} .buttons > * {flex: 1 1 0; display: flex; align-items: center; justify-content: center} /* Slide number box. */ #slidenr {display: block; margin: 1em 0; text-align: center; padding: 0.3em; max-width: 40.889em} /* Slides and video. Scale them down to about 80% of the window for windows less than 65em wide, otherwise use their normal size (about 41em). */ .slide {font-size: 2vw; width: 40.889em; height: 23em; border: none; outline: thin solid #444; margin: 1em 0; object-fit: contain; display: block; box-shadow: none} #video {display: block; font-size: 2vw; width: 40.889em; height: 23em; border: none; margin: 1em 0} audio#video {height: auto; min-height: 2em} /* Smaller if audio */ @media (min-width: 65em) { .slide, #video {font-size: 1em} } </style> <link rel="stylesheet" href="../talk-ui.css"> <link rel=first href="../"> <link rel=prev href="derhak"> <link rel=next href="russell"> <script src="../parser.js"></script> <meta name="twitter:site" content="@w3c"> <meta property="og:title" content="Canvas, WebGL, and WebGPU by Christopher Cameron (Google), 2021 W3C Workshop on Wide Color Gamut and High Dynamic Range for the Web"> <meta property="twitter:title" content="Canvas, WebGL, and WebGPU by Christopher Cameron (Google), 2021 W3C Workshop on Wide Color Gamut and High Dynamic Range for the Web"> <meta property="og:description" content="Christopher Cameron (Google)'s presentation given at the W3C Workshop on Wide Color Gamut and High Dynamic Range for the Web"> <meta name="twitter:card" content="player"> <meta property="og:video" content="https://youtube.com/v/fHbLbVacYw4"> <meta property="twitter:player" content="https://youtube.com/embed/fHbLbVacYw4"> <meta name="twitter:image" content="https://www.w3.org/Graphics/Color/Workshop/media/twitter-banner.png"> <meta property="twitter:player:width" content="360"> <meta property="twitter:player:height" content="200"> </head> <body> <form id=form><!-- form to request a page in kiosk mode --></form> <header class="header"> <div id=banner> <div> <p> <a href="https://www.w3.org/"><img alt="W3C" src= "/Icons/WWW/w3c_home_nb-v.svg" height=48 width=72></a> </p> <div id=banner-image> <h1> W3C Workshop<br>on Wide Color Gamut<br> and High Dynamic Range<br> for the Web </h1> </div> <p> A virtual event with pre-recorded talks and interactive sessions, July 2021 </p> </div> </div> <nav class="menu" id="menu"> <ul> <li> <a href="../../">Overview</a> </li> <li> <a href="../../cfp.html">Call for Participation</a> </li> <li><a href="../../talks.html">Talks</a></li> <li> <a href="../../speakers.html">Apply as a speaker</a> </li> </ul> </nav> </header> <main id=main class="main"> <section id=home> <h2> Canvas, WebGL, and WebGPU </h2> <p> Presenter: <strong>Christopher Cameron (Google)</strong><br> Duration: <strong>9 min</strong><br> Slides: <a href="../Cameron.pdf" ><strong>download</strong></a> </p> <p class=buttons> <button form=form type=submit class="picto im-angle-left" formaction="derhak#main" >Previous: Using iccMAX for HDR color management</button> <a href="../../talks.html" class="button picto im-data">All talks</a> <button form=form type=submit formaction="russell#main" >Next: Deep Dive on HDR, WCG and Linear Rendering in WebGL and WebGPU<span class="picto im-angle-right"></span></button> </p> </section> <section id=talk> <h2> Slides & video </h2> <div id=player> <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "VideoObject", "name": "Canvas, WebGL, and WebGPU", "description": "Christopher Cameron (Google)'s presentation given at the W3C Workshop on Wide Color Gamut and High Dynamic Range for the Web", "thumbnailUrl": "https://videodelivery.net/49569950a25d22ac36095f0ce95749dd/thumbnails/thumbnail.jpg", "uploadDate": "2021-08-15T13:00:00+02:00", "duration": "PT9M0S", "embedUrl": "https://iframe.videodelivery.net/49569950a25d22ac36095f0ce95749dd" } </script> <iframe id=video width=640 height=360 title="Canvas, WebGL, and WebGPU" src="https://iframe.videodelivery.net/49569950a25d22ac36095f0ce95749dd" frameborder=0 allow="accelerometer; autoplay; encrypted-media; picture-in-picture" allowFullScreen=""></iframe> <div id=slides class=fade-in role=region aria-live=off aria-label="Slide container"> <div id="slide-1" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=1" aria-label="Slide 1 of 20"><noscript><a href="../Cameron.pdf#page=1">Slide 1</a></noscript></div> <div lang="en"> <p>Hi, my name is Chris Cameron.</p> <p>I'm a software engineer at Google working on Chrome and today we're going to be talking about 2D Canvases upcoming support for wide color gamut and high dynamic range.</p> </div> <div id="slide-2" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=2" aria-label="Slide 2 of 20"><noscript><a href="../Cameron.pdf#page=2">Slide 2</a></noscript></div> <div lang="en"> <p>So first we're going to start looking at wide color gamut and a good place to start is all the wide color gamut</p> </div> <div id="slide-3" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=3" aria-label="Slide 3 of 20"><noscript><a href="../Cameron.pdf#page=3">Slide 3</a></noscript></div> <div lang="en"> <p>content that's out there on the web already.</p> </div> <div id="slide-4" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=4" aria-label="Slide 4 of 20"><noscript><a href="../Cameron.pdf#page=4">Slide 4</a></noscript></div> <div lang="en"> <p>So the first place where one is likely to encounter wide color gamut content is in media images, pngs, jpgs, other image types include within them or can include within them a color space.</p> <p>And that whole space can be anything.</p> <p>And so that's one place where wide color gamut content already exists on the web.</p> </div> <div id="slide-5" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=5" aria-label="Slide 5 of 20"><noscript><a href="../Cameron.pdf#page=5">Slide 5</a></noscript></div> <div lang="en"> <p>Another place where wide color gamut content already exists on the web is in CSS colors.</p> <p>So most people are used to writing colors in CSS using the the #840628 syntax or using the RGB(132, 6, 40) syntax.</p> <p>One thing that's kind of clear about this format of writing color is that it's 8-bit.</p> <p>But one thing that people may not be aware of is that they're specifying an sRGB color.</p> <p>It's not in some nebulous color space.</p> </div> <div id="slide-6" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=6" aria-label="Slide 6 of 20"><noscript><a href="../Cameron.pdf#page=6">Slide 6</a></noscript></div> <div lang="en"> <p>These colors are in sRGB and in CSS Color Level 4 which has been around for quite some time.</p> <p>There's the ability to express CSS colors that are not just sRGB.</p> <p>So CSS Color Level 4 introduces the snazzy syntax in these last two bullet points where you say color and then a color space and then a bunch of floating point values.</p> <p>And one can say sRGB as the color space or one can say display-p3 as the color space there are a number of other predefined color spaces that could be used.</p> <p>This is something that should be kept in mind because a lot of the color spaces that we're adding for Canvas are coming from this syntax here.</p> </div> <div id="slide-7" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=7" aria-label="Slide 7 of 20"><noscript><a href="../Cameron.pdf#page=7">Slide 7</a></noscript></div> <div lang="en"> <p>So moving onto Canvas, what's the situation today?</p> <p>Well, Canvas 2D Canvas as an API is color managed.</p> <p>And the bitmap that's created for the Canvas the output of the Canvas is de facto sRGB.</p> <p>Now, what do I mean by color managed?</p> <p>I mean that every input, everything that's drawn to a Canvas has a color space associated with it.</p> <p>Oftentimes that color space is sRGB but in the case of images or other things it may not be.</p> <p>The color managing means that all those inputs are converted from whatever color space they're in to sRGB when they're drawn.</p> </div> <div id="slide-8" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=8" aria-label="Slide 8 of 20"><noscript><a href="../Cameron.pdf#page=8">Slide 8</a></noscript></div> <div lang="en"> <p>So as a concrete example, let's take this this pseudo-code where I, I have my Canvas and I create a 2D context to draw into it.</p> <p>I have myDisplayP3Image that I'm drawing and I'm going to draw a CSS color.</p> <p>What happens today?</p> <p>Everything that doesn't fit in sRGB is just chopped off.</p> <p>So you can draw a wide color gamut content to a Canvas, but it's just going to be clipped to sRGB because Canvas is de facto sRGB.</p> <p>The big change coming to Canvas is that we can say we want that backing bitmap to be in something besides sRGB</p> </div> <div id="slide-9" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=9" aria-label="Slide 9 of 20"><noscript><a href="../Cameron.pdf#page=9">Slide 9</a></noscript></div> <div lang="en"> <p>like, for instance, display-p3.</p> <p>And so this is the new syntax.</p> <p>And when you specify this then all those colors that were getting clipped before are now going to appear as actual full display-p3 colors.</p> <p>Very small change.</p> </div> <div id="slide-10" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=10" aria-label="Slide 10 of 20"><noscript><a href="../Cameron.pdf#page=10">Slide 10</a></noscript></div> <div lang="en"> <p>Similarly for the image data API this is an API that allows you to be represent the bitmap image for mostly CPU side pixel manipulation.</p> <p>It too is de facto sRGB.</p> </div> <div id="slide-11" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=11" aria-label="Slide 11 of 20"><noscript><a href="../Cameron.pdf#page=11">Slide 11</a></noscript></div> <div lang="en"> <p>So if I were to have this code where I create an image data and I write these pixel values these pixel values that I'm writing are sRGB values.</p> <p>And what I call put image data which is going to draw this image to the context.</p> <p>This data is considered sRGB and it's going to be converted to whatever the Canvas is.</p> <p>And one thing that people would probably want to do is to be able to specify image data that is not just stuck</p> </div> <div id="slide-12" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=12" aria-label="Slide 12 of 20"><noscript><a href="../Cameron.pdf#page=12">Slide 12</a></noscript></div> <div lang="en"> <p>in being sRGB and the syntax for doing that is just this.</p> <p>And when you create this image data the image here that has an attribute that's going to be the color space and all the data is pixel data in that color space.</p> <p>So the meaning of these pixel values changed from before when there was no color space specified and it was sRGB by default to after when now these are display-p3 pixel values.</p> </div> <div id="slide-13" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=13" aria-label="Slide 13 of 20"><noscript><a href="../Cameron.pdf#page=13">Slide 13</a></noscript></div> <div lang="en"> <p>The final API that's being changed to add support for wide color gamut is image bitmap.</p> <p>Now image bitmap is used for efficient asynchronous bitmap representations, there are a number of different uses.</p> <p>I'm going to focus on web GL just for the purpose of example and it is de facto sRGB.</p> </div> <div id="slide-14" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=14" aria-label="Slide 14 of 20"><noscript><a href="../Cameron.pdf#page=14">Slide 14</a></noscript></div> <div lang="en"> <p>In this example, I'm loading a ball, er, a blob which is going to fetch data from this URL ordinarily would be done asynchronously.</p> <p>And then when I get that blob, I call create image bitmap to decode whatever that blob image was into a bitmap, and this is done asynchronously.</p> <p>And then finally I had this bitmap data and I pass it into texImage2D to upload it to a texture.</p> </div> <div id="slide-15" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=15" aria-label="Slide 15 of 20"><noscript><a href="../Cameron.pdf#page=15">Slide 15</a></noscript></div> <div lang="en"> <p>Well, the new parameter that's coming for image bitmap is a color space parameter where I can say when you're decoding that blob also convert it into the following color space.</p> <p>And because it's being done at decode time and being done asynchronously it can be extra efficient to do here.</p> <p>And then this bitmap here will be whatever was in this image at this URL converted to display-p3.</p> </div> <div id="slide-16" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=16" aria-label="Slide 16 of 20"><noscript><a href="../Cameron.pdf#page=16">Slide 16</a></noscript></div> <div lang="en"> <p>So that's it for wide color gamut that is pretty well baked and on its way out.</p> <p>Something that is more in progress is high dynamic range for 2D Canvas.</p> </div> <div id="slide-17" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=17" aria-label="Slide 17 of 20"><noscript><a href="../Cameron.pdf#page=17">Slide 17</a></noscript></div> <div lang="en"> <p>Now let's start where we did for wide color gamut and talk about where people encounter high dynamic range content either on the web or elsewhere.</p> <p>So on the web there's already support for HDR media, images or videos.</p> <p>And that content comes in either using Hybrid Log Gamma as its transfer function - as its color space, to abuse the terminology a bit - or PQ Perceptual Quantizer.</p> <p>And it's usually 10 bits per pixel.</p> <p>Meanwhile, video games or things doing physically based rendering have been using extended linear sRGB for a long time.</p> <p>And they use 16 bit floating point.</p> <p>And so they allow for writing values that are greater than one.</p> <p>So if you write the value two, that's just going to be twice the brightness of one, whatever one is.</p> </div> <div id="slide-18" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=18" aria-label="Slide 18 of 20"><noscript><a href="../Cameron.pdf#page=18">Slide 18</a></noscript></div> <div lang="en"> <p>And so what's the proposal.</p> <p>Well, we need more color spaces and we need more bits.</p> <p>So the proposal is to add new color spaces with rec2100-hlg and rec2100-pq as color spaces.</p> <p>Also sRGB-linear as a color space, and for creating the 2D context, we're going to want more than the 8 bit's we get by default.</p> <p>So one option would be to have 10 bits per pixel or alternatively also to have 16 bits per pixel.</p> <p>These are all options that we're considering.</p> </div> <div id="slide-19" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=19" aria-label="Slide 19 of 20"><noscript><a href="../Cameron.pdf#page=19">Slide 19</a></noscript></div> <div lang="en"> <p>Now high dynamic range has some complications. for one it uses a lot more power.</p> <p>You have more colors, more power, more bits.</p> <p>You don't want to use it unless you really need it.</p> <p>So we're going to make sure that's something that the user opts into rather than making it something that we try to intelligently detect.</p> <p>Fingerprinting makes things a lot more complicated for high dynamic range.</p> <p>A lot of times when people want to generate HDR content something they want to know in order to use it all throughout the pipeline is for instance the maximum brightness of their display.</p> <p>And that's something that we can't actually give in all of its bits to web applications because that's a lot of bits for fingerprinting.</p> <p>And then a third thing that makes life more complicated is how do you convert between these HR, er, these HDR color spaces?</p> <p>We have PQ, we have HLG we have just regular SDR and we have this extended linear space.</p> <p>There is a spec, ITU 2408, that is an option to be considered.</p> <p>It may not work for everyone.</p> <p>And for the people it doesn't work for it adds a lot of complicated math.</p> </div> <div id="slide-20" class="slide" data-fmt="pdf" data-src="../Cameron.pdf#page=20" aria-label="Slide 20 of 20"><noscript><a href="../Cameron.pdf#page=20">Slide 20</a></noscript></div> <div lang="en"> <p>So that brings us back to the front page which is where we talked about.</p> <p>We talked about wide color gamut, and we talked about a high dynamic range in the context of 2D Canvas and what's coming down the pipeline for that.</p> </div> <div lang="en"> <p>Thanks for taking the lesson.</p> <p>And I also want to thank a number of people who've helped a lot with educating me and also with coming up with these specifications, that includes but it's definitely not limited to Joe Drago at Netflix, Lars Borg at Adobe, Ken Russell at Google and Jeff Gilbert at Mozilla.</p> <p>Thank you.</p> </div> </div><!-- id=slides --> </div><!-- id=player --> </section><!-- id=talk --> <section id=extrabuttons> <p class=buttons> <button form=form id=prevtalk type=submit formaction="derhak#main" class="picto im-angle-left">Previous: Using iccMAX for HDR color management </button> <a id=alltalks href="../../talks.html" class="button picto im-data">All talks</a> <button form=form id=nexttalk type=submit formaction="russell#main" >Next: Deep Dive on HDR, WCG and Linear Rendering in WebGL and WebGPU<span class="picto im-angle-right"></span></button> </p> </section> </main> <footer class="footer" id="footer"> <p> W3C is proud to be an open and inclusive organization, focused on productive discussions and actions. Our <a href= "https://www.w3.org/Consortium/cepc/">Code of Ethics and Professional Conduct</a> ensures that all voices can be heard. Questions? Contact Chris Lilley <<a href= "mailto:chris@w3.org">chris@w3.org</a>>. </p> <p> Suggestions for improving this workshop page, such as fixing typos or adding specific topics, can be made by opening a <a href= "https://github.com/w3c/web-wcg-hdr-workshop">pull request on GitHub</a>, or by emailing Chris Lilley <<a href= "mailto:chris@w3.org">chris@w3.org</a>>. </p> </footer> <!--<script src="script.js"></script>--> <script> let captions = [ { "language": "en", "label": "English", "src": "../Cameron.vtt", "mode": "hidden", "cues": [], "activeCues": [ {"text": ""} ] }, ] </script> <script src="https://embed.videodelivery.net/embed/sdk.latest.js"></script> <script src="https://unpkg.com/pdfjs-dist@2.8.335/build/pdf.js"></script> <script src="https://unpkg.com/pdfjs-dist@2.8.335/web/pdf_viewer.js"></script> <script src="../pdf-loader.js"></script> <script src="../talk-sync.js"></script> </body> </html>