[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Public WebGL] The Newly Expanded Color Space Issue



On Mon, Sep 6, 2010 at 8:06 PM, Chris Marrin <cmarrin@apple.com> wrote:
>
> Our recent conversation about color spaces and texImage2D has brought up a more basic question: what color space is the WebGL Canvas? We need to decide that before we go any further. Choices:
>
> 1) sRGB. I proposed this as the first choice because I claimed that this is the color space used by 2D Canvas. My reasoning for that claim comes from 2 places:
>
>        http://www.w3.org/TR/html5/the-canvas-element.html#color-spaces-and-color-correction
>
> states that "In user agents that support CSS, the color space used by a canvas element must match the color space used for processing any colors for that element in CSS". Furthermore in the CSS 2.1 spec at:
>
>        http://www.w3.org/TR/CSS21/syndata.html#color-units
>
> states that "All RGB colors are specified in the sRGB color space". Since CSS colors are sRGB, it follows that the Canvas should be sRGB.
>
> 2) Linear. I proposed this as the second choice because I claimed that this is the color space used, by convention, by OpenGL. If you look here:
>
>        http://www.opengl.org/registry/specs/EXT/framebuffer_sRGB.txt
>
> it states: "Conventionally, OpenGL assumes framebuffer color components are stored in a linear color space". So since OpenGL uses linear it follows that the WebGL Canvas should be linear.
>
>
> There are strong opinions on both sides. Some say that an sRGB canvas would be too difficult to write shaders for and you'd have to rewrite all your existing OpenGL apps. Others say that a linear canvas would have insufficient resolution in the dark areas and it would cause banding.
>
> I'm not qualified to argue any more. So color space experts, please have at it. But keep it civil, or I swear I will send you all to your rooms and there will be NO ice cream tonight! :-)

I advocate option 1.  I'll try to bullet all my reasons separately for
easier discussion/argument.

* Practically all current realtime display systems that have 8-bit per
channel framebuffers expect gamma'd data.  This includes all
mainstream PC graphics cards and all game consoles.  I assume it
includes all relevant mobile platforms but I don't have first-hand
knowledge.

* This has been the status quo for at least 20 years (though the
precise gamma conversion has become more standardized over time).

* There are some systems (really modes) that use linear framebuffers
-- they generally involve higher depth or floating point framebuffers.
 Since framebuffer bandwidth remains an important bottleneck even with
the latest hardware, I feel WebGL should not mandate that
implementations use higher depth or floating point framebuffers.

* 8-bit per channel sRGB is inherently higher-fidelity than 8-bit per
channel linear, because linear loses visible information in the dark
parts of images.  See http://tulrich.com/webgl/rgb/linear_vs_srgb.html

* If WebGL output must pass through a linear 8-bit per channel
framebuffer, it will be impossible for any WebGL app to display subtle
dark details.  Other technologies like 2D canvas and CSS transforms
won't have this problem.  This will be a competitive disadvantage of
WebGL, for any app that wants to accurately show photographic imagery.

* Browsers currently work with sRGB data.  Images and 2D canvas are
stored and processed in sRGB or equivalent.  Making an exception for
WebGL creates extra implementation work, and opportunities for
bugs/divergences.

* Not using sRGB would create an incompatibility between WebGL and all
other mainstream OpenGL (and D3D/console) systems.

* Choosing sRGB will shut me up.

Stipulations:

* It is true that OpenGL defines all its operations in terms of linear
operations on color components.  Whereas the inputs and outputs are
normally in sRGB or equivalent.  This leads to perceptual
non-linearities in filtering and (straightforward) lighting.

  - However, developers have been dealing with this forever, it's
nothing new.  Nearly all developers tune their algorithms by eye
(there may be a few exceptions in the scientific or simulation
communities).

  - With programmable shading as in WebGL, lighting is under control
of the application developer.  There is a simple and well-known shader
formula for doing linear lighting calculations with sRGB
inputs/outputs, if linear lighting is important enough to spend 1
extra vector pow() per texture sample and one extra vector pow() at
the end of the fragment shader.  Lately, hardware has provided
EXT_texture_sRGB and EXT_framebuffer_sRGB which essentially eliminate
the extra cost of doing lighting in linear space.

  - Texture sample filtering is harder to compensate for because it is
baked into the hardware.  But the differences are not large.  Lately,
hardware has provided EXT_texture_sRGB which eliminates the filtering
issue.

* It is true that WebGL does not yet have extensions, so
EXT_texture_sRGB and EXT_framebuffer_sRGB are not available.

  - This is hopefully a very temporary situation.  In the meantime,
developers can do what they did before the extensions were available.

* Steve Baker has presented a desire and use case for linear lighting.
 His proposed pipeline goes from linear 8/8/8/8, through OpenGL
(linear by default), to a linear 8/8/8/8 framebuffer.  If the output
of WebGL is defined to be sRGB, he will require one extra vector pow()
operation at the end of his fragment shaders, or else a separate pass
over his linear framebuffer, in order to transform from linear 8/8/8/8
buffer into sRGB.

  - One vector pow() is not make-or-break.  He already has to do this
on all other platforms.

  - If WebGL does the per-pixel pow() instead (e.g. in the browser
compositing pass), apps that are designed to write sRGB will pay for
*two* pow's per pixel -- once to write linear 8/8/8/8, and then again
when the browser composites the WebGL buffer into the display buffer.

  - Several of my friends do linear lighting on consoles/PC, and none
that I know of (other than Steve) use a pipeline like what Steve
proposes.  The published talk on Uncharted 2 lighting goes into great
detail on gamma, and recommends the D3D flavor of the EXT_*_sRGB
extensions.

  - In my humble opinion, Steve should look into EXT_*_sRGB for his
existing platforms.  His blacks will look better and he can eliminate
an extra pow() per pixel.

-T

-----------------------------------------------------------
You are currently subscribed to public_webgl@khronos.org.
To unsubscribe, send an email to majordomo@khronos.org with
the following command in the body of your email: