Bug 89116 - Specular light filters produce dark results
Summary: Specular light filters produce dark results
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: SVG (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Florin Malita
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-06-14 12:25 PDT by Florin Malita
Modified: 2012-06-15 08:56 PDT (History)
7 users (show)

See Also:


Attachments
White light filters should not produce grey rectangles around the target (614 bytes, image/svg+xml)
2012-06-14 12:25 PDT, Florin Malita
no flags Details
Patch (692.25 KB, patch)
2012-06-14 14:34 PDT, Florin Malita
no flags Details | Formatted Diff | Diff
Patch for landing (692.25 KB, patch)
2012-06-15 07:30 PDT, Florin Malita
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Florin Malita 2012-06-14 12:25:25 PDT
Created attachment 147628 [details]
White light filters should not produce grey rectangles around the target

This is most obvious if the light filter overlay is not clipped (see attached test).

FELighting is applied in unmultiplied space, but the alpha channel is set for premultiplied RGBA. Then when the image is converted to premultiplied for compositing, the RGB values are scaled down resulting in a darker image.
Comment 1 Florin Malita 2012-06-14 14:28:12 PDT
A straightforward fix is to update FELighting to produce premultiplied results (it already does, but stores it in the unmultiplied buffer). Not only does this take care of the darker result, but it also eliminates subsequent unmultiplied->premultiplied conversions needed by feComposite.

Patch coming up.
Comment 2 Florin Malita 2012-06-14 14:34:35 PDT
Created attachment 147656 [details]
Patch
Comment 3 Dirk Schulze 2012-06-14 15:48:12 PDT
Comment on attachment 147656 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=147656&action=review

r=me

> Source/WebCore/ChangeLog:14
> +        for premultiplied values (which causes a dakening of the result upon the

s/dakening/darkening/
Comment 4 Zoltan Herczeg 2012-06-15 00:52:01 PDT
Not sure I totally understand the concept here.

Try to gather what I know:
- This only affects specular lighting, since it is always 1 for diffuse
- The heightmap is based on the alpha channel.
  -> it doesn't matter if the input is pre or unmultiplied
  (perhaps the filter should be enough clever to recognise this)
- The spec says only: Sa = max(Sr, Sg, Sb)

Making the output brighter is a nice idea, but is it really what the spec wants? Unfortunately the SVG spec for filters does not explain a lot of things. Sometimes difficult to know what the authors want...
Comment 5 Florin Malita 2012-06-15 07:20:26 PDT
(In reply to comment #4)
> Not sure I totally understand the concept here.
> 
> Try to gather what I know:
> - This only affects specular lighting, since it is always 1 for diffuse
Right.

> - The heightmap is based on the alpha channel.
>   -> it doesn't matter if the input is pre or unmultiplied
>   (perhaps the filter should be enough clever to recognise this)
Yes (for RGB calculations), but see below.

> - The spec says only: Sa = max(Sr, Sg, Sb)
This is where is matters - this is supposed to be done in premultiplied space: "Unless otherwise stated, all image filters operate on premultiplied RGBA samples."

> Making the output brighter is a nice idea
It's not just brighter, it's really keeping the color correct.

Take a pure green light for example: #00ff00. Then at some point assume we calculate a specular RGB component of (0,128,0). The spec says the alpha should also be 128, so (r,g,b,a) = (0, 128, 0, 128). If you treat this as unmultiplied, then for compositing purposes your light is no longer pure green (#00ff00) but some darker tone (#004000) -> hence the grey artifact in the example. If OTOH (0, 128, 0, 128) is premultiplied, then you're still applying the original color with 50% alpha as intended.
Comment 6 Stephen White 2012-06-15 07:21:59 PDT
(In reply to comment #4)
> Not sure I totally understand the concept here.
> 
> Try to gather what I know:
> - This only affects specular lighting, since it is always 1 for diffuse
> - The heightmap is based on the alpha channel.
>   -> it doesn't matter if the input is pre or unmultiplied
>   (perhaps the filter should be enough clever to recognise this)

As you say, this shouldn't matter either way for correctness, since the filter only takes the alpha.  It might be a little faster this way, however:  if the previous filter outputs a premultiplied result (the more common case), this will save having to do a useless unmultiply step.  Of course, ideally we should just grab the alpha without touching RGB, but that could be a further optimization.

> - The spec says only: Sa = max(Sr, Sg, Sb)
> 
> Making the output brighter is a nice idea, but is it really what the spec wants? Unfortunately the SVG spec for filters does not explain a lot of things. Sometimes difficult to know what the authors want...

This part is for correctness.  My reading that Florin's change is correct is from here:  "Unless otherwise stated, all image filters operate on premultiplied RGBA samples. Filters which work more naturally on non-premultiplied data (feColorMatrix and feComponentTransfer) will temporarily undo and redo premultiplication as specified."

By requesting an unmultiplied result buffer, the way the code was before, the next filter will cause the premultiply to happen again,
leaving us with  Sr = Sr * Sa, Sg = Sg * sA, Sb * Sa (where Sa was the previously-computed max of the unmultiplied colours).  If that was what was desired, presumably that would have been explicitly stated in the feSpecularFilter description.  Since it's not listed as an exception to the "all filters produced premultiplied alpha" rule, I think it's safe to say the original (Sr, Sg, Sb) as described in the feSpecularFilter docs are assumed to be already premultiplied.
Comment 7 Florin Malita 2012-06-15 07:30:45 PDT
Created attachment 147808 [details]
Patch for landing
Comment 8 Zoltan Herczeg 2012-06-15 07:42:13 PDT
Thnaks for the explanation.
Comment 9 WebKit Review Bot 2012-06-15 08:56:48 PDT
Comment on attachment 147808 [details]
Patch for landing

Clearing flags on attachment: 147808

Committed r120467: <http://trac.webkit.org/changeset/120467>
Comment 10 WebKit Review Bot 2012-06-15 08:56:52 PDT
All reviewed patches have been landed.  Closing bug.