Brightness filter in CSS Filters spec is wrong?

Currently, the spec here:

	https://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent

describes the equivalent SVG filter for the CSS brightness() filter. It shows:

	<feFuncR type="linear" slope="[amount]"/>

and similar functions for the other channels. But this effectively multiplies the color values by amount, which I believe is wrong. Looking at the Core Image Filter Reference for the CIColorControls filter:

	http://developer.apple.com/library/mac/documentation/graphicsimaging/reference/CoreImageFilterReference/Reference/reference.html#//apple_ref/doc/filter/ci/CIColorControls

it shows the formula:

	color.rgb + vec3(brightness)

which simply adds the brightness value (with clamping). Looking at other definitions of brightness on the web, they seem to agree with the Core Image approach. WebKit currently implements brightness using the definition in the CSS Filters spec and the results look wrong. A color that is (1,0,0) will always be brighter or darker shades of red. It can never be brighter than 100% red. But brightness is supposed to increase the apparent luminosity of a color, so the maximum brightness should always be pure white. But the current CSS Filter algorithm can never produce white from a pure red pixel, while  the algorithm used by Core Image can.

Photoshop seems to use something more complex. Perhaps it is converting the image to HLS, adjusting the L value, and converting back. That would be the most accurate algorithm.

Of course the web treats us to infinite detail on this subject. I think the issues are summarized nicely in this paper:

	http://www.kweii.com/site/color_theory/2007_LV/BrightnessCalculation.pdf

It shows 3 ways of computing brightness. One of them is the Core Image algorithm, but none of them is the current CSS Filter algorithm. If we were to change it, the new formula would simply be:

	<feFuncR type="linear" intercept="[amount]"/>
	<feFuncG type="linear" intercept="[amount]"/>
	<feFuncB type="linear" intercept="[amount]"/>

the default value would be 0. Negative values would make the image darker, with -1 giving a completely black image and 1 giving one that is completely white.

-----
~Chris
cmarrin@apple.com

Received on Friday, 20 January 2012 18:26:32 UTC