- From: Michael Mullany <michael@sencha.com>
- Date: Tue, 5 Nov 2013 00:12:13 -0800
- To: Dirk Schulze <dschulze@adobe.com>
- Cc: "public-fx@w3.org" <public-fx@w3.org>, www-svg list <www-svg@w3.org>
- Message-ID: <CABTYPJnoHvB=pkVqs2KcJkQ7n8L6ZQ-u7fQ87pDdijeNqcj90Q@mail.gmail.com>
On Mon, Nov 4, 2013 at 10:30 PM, Dirk Schulze <dschulze@adobe.com> wrote: > > On Nov 5, 2013, at 1:01 AM, Michael Mullany <michael@sencha.com> wrote: > > > On Mon, Aug 26, 2013 at 9:28 PM, Dirk Schulze <dschulze@adobe.com> wrote: > >> Hi, >> >> This is a follow up on Stephen White's mail "Filter Effects and High >> DPI"[2] >> >> The Filter Effects spec[1] has a couple of filter primitives that are >> resolution dependent. Namely: feConvolutionMatrix, feDiffuseLighting, >> feSpecularLighting and feCustom. >> >> With removing 'filterRes', there is just 'kernelUnitLength' that can be >> used to "hard code" a resolution for a primitive. 'filterRes' defined the >> resolution for the whole filter chain which reduced or increased pixel >> density for each filter primitive instead of one. This either caused >> unnecessary oversampling of filter operations but more often: unnecessary >> reduction of quality. With 'kernelUnitLength' the affect of over- or >> undersampling can be localized to exactly one primitive where the primitive >> values can not be scaled for resolution independent results. >> >> If 'kernelUnitLength' is not set, all the primitives in the introduction >> may depend on the device pixel ratio and are therefore platform dependent. >> This is actually hardly a "retina" vs "normal" screen problem. SVG is >> scalable by nature and therefore you can see the problem on any screen >> today. Open the following example in a browsers and resize the window: >> >> >> http://www.w3.org/Graphics/SVG/Test/20110816/svg/filters-conv-01-f.svg >> >> You'll see that you don't have consistent results. If you make the window >> smaller, the top left image gets more blurry and the top right image more >> sharpen. Same happens if you zoom into a page where one of the above >> primitives was applied. >> >> We could create stable results by default. UAs could set >> 'kernelUnitLength' such that the kernel size is always relative to a CSS >> pixel in the current local coordinate system of the filtered object. This >> is something that is nearly impossible to determine for the author if he >> wants to use the same filter on different objects. With the auto calculated >> 'kernelUnitLength' the proportion of the filter chain result looks always >> the same across platforms but might be more pixelated on one platform and >> less pixelated on another one. >> >> It is unclear what is better for the users: >> * best results that are highly platform dependent and indeed differ >> significantly, or >> * platform independent results that might be pixelated. >> >> During my research I couldn't find one SVG example where the above >> primitives are used in combination of either 'filterRes' or >> 'kernelUnitLength'. Not even in the SVG test suite. That means these >> examples in the web out there are all suffering from device and zoom >> dependent filter results. >> >> I would even suggest removing 'kernelUnitLength' as well and choose one >> of the above two ways (high DPI but resolution dependent results, or >> pixelated proportion stable results). Or let the author choose between one >> of the two options and have one as fallback. >> >> Does anyone have a comment? >> > > > I got around to doing a thorough testing of feDiffuseLighting + > fePointLight cross browser and generated a test page for people to play > with. > > The page is here: http://codepen.io/mullany/pen/wKJeu (note this takes a > while to render in IE10 due to lack of support for objectBoundingBox units > for kernelUnitLength) > > It's not very surprising that there is not much content using these > settings because they don't work consistently cross browser. Here's what I > found: > > - kernelUnitLength: supported by IE10, Firefox (no support in Safari > or Chrome) > - filterRes: supported by Chrome, Safari, Firefox (no support in IE10) > - primitiveUnits = userSpaceOnUse -> supported everywhere > - primitiveUnits = objectBoundingBox -> supported by Firefox, (no > support in Safari, Chrome, IE10: units are interpreted as userSpace units) > - This makes kernelUnitLengths specified in OBB units cause very > very long render times in browsers (aka IE10) that support > kernelUnitLength, but don't support objectBoundingBox units - because it > thinks I'm asking for a very small kernelUnitLength > > This test page raised one or two notes for the current spec: > > - The spec is not clear what Z position units are calculated relative > to, when primitiveUnits = objectBoundingBox -> X? Y? Some average thereof? > - The spec is not clear that surfaceScale units are in pixels, not in > primitiveUnits (or if they're supposed to be primitiveUnits, it should say > that - no browser currently supports this) > > In any case, the use case I'm running into is not a high dpi vs. low dpi > problem (because OBB units should be able to solve this, I think?) Instead, > it's the fact that Firefox (specifically) chooses a fast, low quality > default for lighting effects which are too coarse to use in image filters. > The mozilla implementor has told me to use a higher filterRes, but since > all positions are scaled by the ratio of filterRes to default filterRes > (aka when you double the filterRes, the X, Y and Z positions of your image > source are also scaled up by 2x), you end up with what is effectively a new > unit system just for lightsource positions that has nothing to do with any > other unit system (unless you also reduce the kernelUnitLength to > compensate). [As an aside, the practical effect of this in Firefox was no > increase in quality (and I've filed a bug against that)]. > > It would all be a lot simpler if there was an attribute similar to > shape-rendering (filter-rendering?) that would allow optimizeSpeed vs. > optimizeQuality for these primitives. > > I need to verify your test case. All arguments are supposed to be pixels > and therefore are just integer and floats (floats for oversampling) and > don’t have px, cm or any other length value. > Just to clarify, the following lighting related units are defined in primitiveUnits, not pixels in both the SVG 1.1 spec and the current filter effects 1.0 draft - kernelUnitLength in feDiffuseLighting & feSpecularLighting - X, Y,Z in fePointlight - X, Y, Z, PointsAtX, PointsAtY, PointsAtZ, in feSpotlight > I agree that Firefox implemented some values like stdDeviation from > feGaussianBlur relative to the value of primitiveUnits. A reason why WebKit > did it as well. Not sure if that was the initial intension of the spec > though. I rather think that primitiveUnits should just be taken into > account for x,y,width and height of the subregions, but kernelUnitLength is > indeed one use case where it makes sense to have it relative to > primitiveUnits. I’ll add an issue to the spec. > In both SVG 1.1, and in the current filter effects 1.0 draft - stdDeviation for GaussianBlur as well as kernelUnitLength for feDiffuseLighting and feSpecularLighting are all defined as primitiveUnits. From the specs: stdDeviation = "*<number-optional-number> <http://www.w3.org/TR/SVG/types.html#DataTypeNumberOptionalNumber>*" The standard deviation for the blur operation. If two <number><http://www.w3.org/TR/SVG/types.html#DataTypeNumber>s are provided, the first number represents a standard deviation value along the x-axis of the coordinate system established by attribute ‘primitiveUnits’<http://www.w3.org/TR/SVG/filters.html#FilterElementPrimitiveUnitsAttribute> on the ‘filter’ <http://www.w3.org/TR/SVG/filters.html#FilterElement> element. ‘kernelUnitLength’<http://www.w3.org/TR/SVG/filters.html#feDiffuseLightingKernelUnitLengthAttribute>, in combination with the other attributes, defines an implicit pixel grid in the filter effects coordinate system (i.e., the coordinate system established by the ‘primitiveUnits’<http://www.w3.org/TR/SVG/filters.html#FilterElementPrimitiveUnitsAttribute> attribute) > > That said, your conclusion that WebKit and Blink do not support > primtitiveUnits in general is not correct. in the cases described above, > both engines should take primitiveUnits into account. > I should have been clearer - I was talking solely about the context of the test page - meaning that they don't currently support primitiveUnits=objectBoundingBox specifically for fePointlight X,Y,Z positions. No generalization was intended (although I also know that feSpotlight positions also do not currently support objectBoundingBox units in Chrome or Webkit) > > I compare Z to the value of z on transform-origin or perspective-origin > from CSS Transforms. You can not have percentage values there because you > don’t know how they would be relative to the x and y dimension. Therefore, > Z should always operate in userSpaceOnUse. I'll add an issue to the spec. > I think I inappropriately slandered the draft spec wrt its definition of Z -> The spec currently states: "Z location for the light source in the coordinate system established by attribute ‘primitiveUnits’<http://www.w3.org/TR/filter-effects/#FilterElementPrimitiveUnitsAttribute> on the <filter> <http://www.w3.org/TR/filter-effects/#FilterElement> element, assuming that, in the initial coordinate system<http://www.w3.org/TR/2011/REC-SVG11-20110816/coords.html#InitialCoordinateSystem> , the positive Z-axis comes out towards the person viewing the content and assuming that one unit along the Z-axis equals one unit in X and Y<http://www.w3.org/TR/SVG11/coords.html#Units_viewport_percentage> " one unit in X and Y is in turn defined as " sqrt((*actual-width*)**2 + ( *actual-height*)**2))/sqrt(2)." I can see many use cases where you want X, Y and Z of a pointlight source defined in objectBoundingBox units, so you can apply the same filter to a bunch of differently sized content for example for consistent embossing, without having to recalculate Z units . So the current spec language seems fine to me. > > filterRes was deprecated and removed from the spec. It is just > kernelUnitLength that is left. > > I am not convinced if it is worth it to keep kernelUnitLength. You never > know how kernelUnitLength is relative to device units OR to your object, > see previous discussions. So you are better on with having high DPI results > but platform dependent or you want to have it exactly depending on your > userSpaceInUse coordinates which probably will reduce quality. Of course, > if you put it in userSpaceOnUse, there are cases where you could > ridiculously increase the pixel density and the browser may need to reduce > it again or runs out of memory. Example: > > <g transform=“scale(0.0001)”> > <g filter=“url(#filter)”> > <rect transform=“scale(100)” width=“1000” height=“1000"/> > </g> > </g> > > The resulting rect size would be 100x100, yet the filtered object would be > 100000x100000. > > So even if we add a flag to switch between device pixels and > userSpaceOnUse, it would still just be a hint for the UA. > Given that it's already implemented in both Firefox and IE10+, I'd vote for retaining kernelUnitLength as the way to poke the UA to do the "right thing" however the developer/author chooses to define that, rather than introducing a new attribute. > > Greetings, > Dirk > > > > > > > > > > >> >> Greetings, >> Dirk >> >> >> [1] http://dev.w3.org/fxtf/filters/ >> [2] http://lists.w3.org/Archives/Public/public-fx/2013JanMar/0149.html >> > > > > -- > www.sencha.com > "Amazing Apps with Web Technologies" > > > -- www.sencha.com "Amazing Apps with Web Technologies"
Received on Tuesday, 5 November 2013 08:13:12 UTC