W3C home > Mailing lists > Public > www-style@w3.org > January 2012

[css3-images] We should use linear RGB color space when doing gradients (and transitions, and ...)

From: Witold Baryluk <baryluk@smp.if.uj.edu.pl>
Date: Sat, 14 Jan 2012 05:57:34 +0100
To: "www-style@w3.org" <www-style@w3.org>
Message-ID: <20120114045733.GI11692@smp.if.uj.edu.pl>
Hi,

I just read draft http://www.w3.org/TR/2012/WD-css3-images-20120112/
and there is notion of RGBA premultiplied space when using
interpolations between color stops in gradient rendering.

I understand somehow why premultiplication is done, but this is only
to take somehow into account a transparency.

Hower I think whole linear interpolation should be done in linear color
space, which sRGB is not (and yes, according to
http://www.w3.org/TR/2011/REC-css3-color-20110607/, are colors we use in
CSSes are sRGB ones). To properly use and operate on sRGB colors, one
must first perform gamma correction (to convert sRGB to linear RGB
space), then do interpolation for each point, and resulting color should
be converted back using gamma correction to sRGB (or other color space
if particular display device needs).

Note: Also most modern GPU can perform gamma corrections (as defined by
sRGB) in hardware (both when reading textures, creating/processing them
proceduraly using shaders [fragment programs], or writing to other
textures and framebuffer).

My reasoning: A gradient from rgb(0,0,0) to rgb(255,255,255) should at
midpoint should have grey color with 50% light intensity of
rgb(255,255,255), which isn't rgb(127,127,127), but approximetly
rgb(190,190,190).

Unofrtunetly not only css-images module have this flaws as I quickly
checked. Even ignoring specifications, most UA implementations have
incorrect handling of color spaces when rendering images (most notable
when resizing/resamling/rotating/etc. them, as well CSS Transforms), and
also when composing multiple semitransparent layers (they are doing
linear combination of background and foreground colors defined in
nonlinear colors space, which is plainly WRONG). I understand some
ignorance how sRGB works can explain part of problem source, and
performance considerations can explain other, but gamma correction is
really simple to do: in one way it can be done using single (small)table
lookup for each color component, in second way it can be done quite
cheaply using simple math, and additionally on any modern GPU, since say
2005, it can be done fully in hardware.

Other problem with not using linear space for operations (like lin.iterpol.),
is that gradients defined using hsl and using rgb, may create
unintuitvly different gradients.


BTW. Same problems applies, when one performs CSS Transition (like
transitioning linearly from color: black, to color: white; in 2s, will
make wrong color at time 1s).

Regards,
Witek

-- 
Witold Baryluk
Received on Saturday, 14 January 2012 04:58:17 GMT

This archive was generated by hypermail 2.3.1 : Tuesday, 26 March 2013 17:20:48 GMT