Svg filters html5 devconf apr 2013

11,212 views
11,693 views

Published on

1 Comment
1 Like
Statistics
Notes
No Downloads
Views
Total views
11,212
On SlideShare
0
From Embeds
0
Number of Embeds
8,688
Actions
Shares
0
Downloads
18
Comments
1
Likes
1
Embeds 0
No embeds

No notes for slide

Svg filters html5 devconf apr 2013

  1. 1. SVG Filters: A GuideFor The PerplexedMichael MullanyCEO 1
  2. 2. Filter Effects‣ Visual transformations made before content is rendered into document ‣ Color manipulations ‣ Convolutions & distortions ‣ Lighting effects‣ 3 Species of Filters ‣ CSS Filters (shorthand filters) ‣ SVG Filters (referenceable from CSS) ‣ Custom Filters (OpenGL based) 2
  3. 3. CSS Filters ‣ Apply filters to any HTML content via CSS ‣ Filter values are transitionable/animatable Blur Invert Contrast Grayscale Hue Rotation Opacity Sepia Brightness Saturation Drop shadow url(#svgfilter)http://html5-demos.appspot.com/static/css/filters/index.html 3 credit: eric bidelman - google
  4. 4. Chrome Mobile Works Playbook 1 + 2 Work too 4Source: caniuse.com
  5. 5. Filters vs. Img or Canvas‣ Just like CSS, Filters help: ‣ Replace images with declarative text ‣ Reduce download sizes ‣ Define once, apply many ‣ Compact syntax‣ Particularly useful ‣ Built-in noise generator, helpful pre-built functions ‣ Easy to replace noise effects for images (compress poorly) ‣ Adding effects to user contributed content ‣ Viewbox units means filters are dimensionless (ish)‣ Animatable with JavaScript (IE10) & <animate> (most other browsers) 5
  6. 6. Y We No Use Already‣ Just available in browsers within last year!‣ Hidden rocks of silent defaults ‣ Sample code - difficult to follow‣ Poor documentation‣ SVG Spec is often “abbreviated”‣ DOM interfaces obscure‣ Not friendly to “paste & tweak” experimentation‣ Special prizes for deciphering SVG animation spec.‣ (XML is strict & sometimes weird) 6
  7. 7. SVG Filters - Basic SchemeInput 1 Op Output 1Input 2 Combine Final OutputInput 1 Op Output 2 7
  8. 8. Filter Syntax<defs> <filter id= “myfilter”> ...filter primitives... </filter> </defs>standard optional SVG element props + primitiveUnits (userspace vs. bounding box) x,y ; width, height (default: -10%, -10%, 120%, 120%) filterRes (resolution of intermediate images) Apply a filter to an element by using the filter property filter = “url(#myfilter)” 8
  9. 9. SVG Filter Toolbox Inputs Operations Lighting Combinations Source ColorMatrix Types Composite SourceAlpha ComponentXfer Diffuse (matte) Blend Image ConvolveMatrix Specular (shiny) Merge Flood (Color Fill) Morphology SourcesTurbulence (Noise) Displacement Distant Light Background Tile | Offset Spot LightPaint/Stroke Color GaussianBlur Point Light 9
  10. 10. Example: Baked Film 10
  11. 11. Baked Film: Example 3.Red1. L2A 2.Blur Light 5. 4.ThreshImage Composite old “Baked Film” Image 11
  12. 12. <filter id="BakedFilm"> 1 <feColorMatrix in = "SourceGraphic" type = "luminanceToAlpha" result= "highlights"/> 2 <feGaussianBlur in="highlights" stdDeviation="4" result="blur"/> <feSpecularLighting in="blur" surfaceScale="15" specularConstant=".8" 3 specularExponent="5" lighting-color="red" result="lightmap"> <feDistantLight azimuth="45" elevation="10"/> </feSpecularLighting> 4 <feComponentTransfer in="lightmap" result="highlights"> <feFuncA type="table" tableValues="0 0 .5 1 1"/> </feComponentTransfer> 5 <feComposite in="SourceGraphic" in2="highlights" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" result="litPaint"/> </filter> 12
  13. 13. <feGaussianBlur in="highlights" stdDeviation="4" result="blur"/> <feSpecularLighting in="blur" surfaceScale="15" specularConstant=".8"<feColorMatrix in = "SourceGraphic" type = specularExponent="5" lighting-color="red" result="lightmap">"luminanceToAlpha" result= "highlights"/> <feDistantLight azimuth="45" elevation="10"/> </feSpecularLighting> 3.Red 1. L2A 2.Blur Light 5. 4.Thresh Image Composite old <feComponentTransfer in="lightmap" result="highlights"> <feFuncA type="table" tableValues="0 0 .5 1 1"/> </feComponentTransfer> <feComposite in="SourceGraphic" “Baked Film” in2="highlights" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" Image result="litPaint"/> 13
  14. 14. Filter Primitives 14
  15. 15. Basic Inputs‣ Source: the default input = whatever the filter has been applied to‣ SourceAlpha: the alpha channel of the source content‣ feImage: any image in URL format <feImage xlink:href="http://somedomain.com/image.jpg"            x="0" y="0" width="100%" height="100%"            preserveAspectRatio="none"/> 15
  16. 16. Color Fill‣ feFlood: colored rectangle‣ x,y, width, height, flood-color, flood-opacity <feFlood x="5" y="10" width="100" height ="100" flood-color="rgb(24,25,250)" flood-opacity= “0.5”> 16
  17. 17. Turbulence‣ feTurbulence - fast noise generator‣ Steam, rippling, marbling, woodgrain etc.‣ Parameters: ‣ baseFrequency: X,Y (higher = more granular) ‣ numOctaves: 1,2,etc. (higher=more detail) ‣ type: fractalNoise (gas) or turbulence (liquid) ‣ seed: reproducible ‣ stitchTiles: edge continuity in tiled results 17
  18. 18. type=turbulence freq 0.05 0.1 0.51 Octave2 Octave4 Octave Not very interesting by itself, but... 18
  19. 19. Add some other filters ... http://codepen.io/mullany/pen/duHbD Help! Please star the webkit bug uncovered by this demo 19 http://code.google.com/p/chromium/issues/detail?id=225594
  20. 20. Transformations 20
  21. 21. ColorMatrix Types‣ 3 shorthands + 1 Matrix ‣ saturate ‣ huerotate ‣ luminancetoAlpha‣ luminancetoAlpha takes brightness and converts it to opacity 21
  22. 22. Full ColorMatrix e.g. factor by which blue channel inputInput is multiplied and added to red channel output Output R R R->R G->R B->R A->R k1 G G R->G G->G B->G A->G k2 B X = B R->B G->B B->B A->B k3 A A R->A G->A B->A A->A k4 1 1 e.g. factor by which red channel input is multiplied and added to alpha channel output adds fixed offset 22
  23. 23. Color Matrix Examples "0.30 0.30 0.30 0 0 0.25 0.20 0.25 0.20 0.25 0.20 0 0 0 0 Sepia 0.00 0.00 0.00 1 0" "0.33 0.33 0.33 0 0 0.33 0.33 0.33 0.33 0.33 0.33 0 0 0 0 Greyscale 0.00 0.00 0.00 1 0" "0.33 0.33 0.33 .5 0 0.00 0.00 0.00 0.00 0.00 0.00 0 0 0 0 Redden 0.00 0.00 0.00 1 0" 23Details(first draft): http://docs.webplatform.org/wiki/svg/elements/feColorMatrix
  24. 24. Live demo: Color Matrix (& alpha manipulation)http://codepen.io/mullany/pen/qJCDk 24
  25. 25. ComponentTransfer‣ Manipulate each color channel independently.‣ 5 Types ‣ identity, table, discrete, linear, gamma ‣ linear: slope*input + intercept ‣ gamma: amp * (input^exponent) + offset ‣ table: (a,b,c) 0->.5 mapped to a->b, .5->1 mapped to b->c. ‣ discrete: (a,b,c) 0->.33 goes to a, .33->.66 goes to b etc. 25Details (my first draft): http://docs.webplatform.org/wiki/svg/elements/feComponentTransfer
  26. 26. Component Transfer Gamma Table Discrete Linear 26
  27. 27. DEMO:Discrete Transforms http://codepen.io/mullany/pen/oAqpF 27
  28. 28. DEMO:Fine-grained shadow control <filter id="f1" x="-20%" y="-20%" width="140%" height="140%"> <feGaussianBlur in="SourceAlpha" result="blurOut" stdDeviation="5"/> <feOffset in="blurOut" result="dropBlur" dx="4" dy="y"/> <feComponentTransfer in="dropBlur" result="dropBlur2"> <feFuncA id="alphaFunc" type="gamma" amplitude="2" exponent=".5" offset="0"/> </feComponentTransfer> <feComposite operator="over" in="SourceGraphic" in2="dropBlur2"/> </filter> http://codepen.io/mullany/pen/fdkmI 28
  29. 29. Convolution 0 0 0 0 1 0 Identity 0 0 01. Take values of pixels around the input pixel + current pixel value2. Multiply by respective matrix value3. Add up the results = value of output pixel 29
  30. 30. feConvolveMatrix‣ <feConvolveMatrix order= “n” kernelMatrix= “values....”/>‣ Optional parameters ‣ Shift matrix position relative to input pixel ‣ Exclude alpha channel ‣ Add a divisor ‣ Add a constant ‣ Change edge settings 30
  31. 31. Patterns-1 -1 -1 2 1 0-1 8 -1 Edges 1 1 -1 Emboss-1 -1 -1 0 -1 -20 -1 0 1 0 0 Motion Blur-1 5 -1 Sharpen 0 1 00 -1 0 0 0 1 (linear)1 1 1 0 -1 01 1 1 Blur 0 2 0 ?1 1 1 0 -1 0 31
  32. 32.   <feConvolveMatrix order="11"  kernelMatrix="            1 0 0 0 0 0 0 0 0 0 0            0 1 0 0 0 0 0 0 0 0 0            0 0 1 0 0 0 0 0 0 0 0 SLOOOW!!            0 0 0 1 0 0 0 0 0 0 0            0 0 0 0 1 0 0 0 0 0 0            0 0 0 0 0 1 0 0 0 0 0            0 0 0 0 0 0 1 0 0 0 0            0 0 0 0 0 0 0 1 0 0 0            0 0 0 0 0 0 0 0 1 0 0            0 0 0 0 0 0 0 0 0 1 0            0 0 0 0 0 0 0 0 0 0 1 " /><feConvolveMatrix order="3"kernelMatrix="            0 -1  0           -1  5 -1            0  -1 0 " />    <feConvolveMatrix order="3"  kernelMatrix="            2  1  0            1  1 -1            0  -1 -2  " /> 32
  33. 33. Morphology “Thicken & Thin”erode 1px dilate 3px dilate 12px in Y Takes min/max of <feMorphology operator="erode" in="SourceGraphic" radius="1" /> each channel in morph radius        33
  34. 34. feDisplacementMap‣ Two inputs: Source & Displacement‣ Specify a color channel from displacement for X and Y‣ For each pixel in Source, displace it from its original position by the color values specified in X and Y 34
  35. 35. Turbulence + Displacement =    <feTurbulence type="fractalNoise" baseFrequency=".1" numOctaves="2" result="turb"/>         <feDisplacementMap in="SourceGraphic" in2="turb" scale="20" xChannelSelector="B"/> 35Help! Please star this webkit bug relating to turbulence: http://code.google.com/p/chromium/issues/detail?id=163853
  36. 36. Lighting‣ Two types ‣ Diffuse (matte) vs. Specular (shiny)‣ Three light sources ‣ Point, distant and spot 36
  37. 37. Light Sources‣ Point light ‣ Looks exactly like a radial gradient in flat space ‣ Specify coords of source & destination‣ Spot light ‣ Specify coords, also control focus and cone angle‣ Distant light ‣ Azimuth (direction) and Elevation ‣ Only useful with bumpmaps 37
  38. 38. Diffuse vs. Specular‣ Diffuse is “regular” lighting, similar to applying semi-transparent gradients over content ‣ Specify a diffuseConstant (how concentrated the light is) ‣ kernelUnitLength‣ Specular adds shiny highlights‣ Both can be used to simulate 3D from 2D content by generating a “bump map” (pseudo z values) from the alpha channel 38
  39. 39. Diffuse Lighting 39
  40. 40. Specular Lighting 40
  41. 41. Lightsource Bug help‣ Please star these webkit bugshttp://code.google.com/p/chromium/issues/detail?id=177623http://code.google.com/p/chromium/issues/detail?id=177624 41
  42. 42. Combinations‣ feMerge: simple z-layering‣ feBlend: shorthand combinations ‣ Normal: (=Merge) ‣ Multiply: Multiply pixel values together ‣ Screen: Sum - Product of pixel values ‣ Darken: Use darker pixel ‣ Lighten: Use lighter pixel 42
  43. 43. Compositing Shorthands for compositing + Arithmetic(!) k1 * A * B + k2 * A + k3 * B + k4 43Source: SVG Spec
  44. 44. DEMO:Animated Text Shadows with Compositing (sorry, no IE) http://codepen.io/mullany/details/plgDv 44
  45. 45. <svg width="800" height="650" viewBox="0 0 800 650"><defs> <filter id="displacement" filterUnits="objectBoundingBox"> <feTurbulence type="fractalNoise" baseFrequency=".1" numOctaves="2" result="turb"> <animate attributeType="XML" attributeName="baseFrequency" values=".1; .12; .1" dur="16s" repeatCount="indefinite"/> </feTurbulence> <feDisplacementMap in="SourceGraphic" in2="turb" scale="20" result="displace" xChannelSelector="B"/> <feGaussianBlur in="displace" result="displaceblur" stdDeviation="1"/> <feComponentTransfer in="displaceblur" result="displaceR"> <feFuncR type="discrete" tableValues=".4 .4"/> </feComponentTransfer> <feComposite operator="over" in2="SourceGraphic" in="displaceR"/></filter> 45
  46. 46. <svg width="800" height="650" viewBox="0 0 800 650"><defs> <filter id="displacement" filterUnits="objectBoundingBox"> <feTurbulence type="fractalNoise" baseFrequency=".1" numOctaves="2" result="turb"> <animate attributeType="XML" attributeName="baseFrequency" values=".1; .12; .1" dur="16s" repeatCount="indefinite"/> </feTurbulence> <feDisplacementMap in="SourceGraphic" in2="turb" scale="20" result="displace" xChannelSelector="B"/> <feGaussianBlur in="displace" result="displaceblur" stdDeviation="1"/> <feComponentTransfer in="displaceblur" result="displaceR"> <feFuncR type="discrete" tableValues=".4 .4"/> </feComponentTransfer> <feComposite operator="in" in2="SourceGraphic" in="displaceR"/></filter> 46
  47. 47. <svg width="800" height="650" viewBox="0 0 800 650"><defs> <filter id="displacement" filterUnits="objectBoundingBox"> <feTurbulence type="fractalNoise" baseFrequency=".1" numOctaves="2" result="turb"> <animate attributeType="XML" attributeName="baseFrequency" values=".1; .12; .1" dur="16s" repeatCount="indefinite"/> </feTurbulence> <feDisplacementMap in="SourceGraphic" in2="turb" scale="20" result="displace" xChannelSelector="B"/> <feGaussianBlur in="displace" result="displaceblur" stdDeviation="1"/> <feComponentTransfer in="displaceblur" result="displaceR"> <feFuncR type="discrete" tableValues=".4 .4"/> </feComponentTransfer> <feComposite operator="xor" in2="SourceGraphic" in="displaceR"/></filter> 47
  48. 48. <svg width="800" height="650" viewBox="0 0 800 650"><defs> <filter id="displacement" filterUnits="objectBoundingBox"> <feTurbulence type="fractalNoise" baseFrequency=".1" numOctaves="2" result="turb"> <animate attributeType="XML" attributeName="baseFrequency" values=".1; .12; .1" dur="16s" repeatCount="indefinite"/> </feTurbulence> <feDisplacementMap in="SourceGraphic" in2="turb" scale="20" result="displace" xChannelSelector="B"/> <feGaussianBlur in="displace" result="displaceblur" stdDeviation="1"/> <feComponentTransfer in="displaceblur" result="displaceR"> <feFuncR type="discrete" tableValues=".4 .4"/> </feComponentTransfer> <feComposite operator="atop" in2="SourceGraphic" in="displaceR"/></filter> 48
  49. 49. <svg width="800" height="650" viewBox="0 0 800 650"><defs> <filter id="displacement" filterUnits="objectBoundingBox"> <feTurbulence type="fractalNoise" baseFrequency=".1" numOctaves="2" result="turb"> <animate attributeType="XML" attributeName="baseFrequency" values=".1; .12; .1" dur="16s" repeatCount="indefinite"/> </feTurbulence> <feDisplacementMap in="SourceGraphic" in2="turb" scale="20" result="displace" xChannelSelector="B"/> <feGaussianBlur in="displace" result="displaceblur" stdDeviation="1"/> <feComponentTransfer in="displaceblur" result="displaceR"> <feFuncR type="discrete" tableValues=".4 .4"/> </feComponentTransfer> <feComposite operator="out" in2="SourceGraphic" in="displaceR"/></filter> 49
  50. 50. http://www.quora.com/Instagram/How-does-Instagram-develop-their-filters e.g. nashville filter 50
  51. 51. 51
  52. 52. <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" > <defs> <filter id="instagram" x="0" y="0" width="100%" height="100%" filterUnits="objectBoundingBox" primitiveUnits="userSpaceOnUse"> <!--Red curve--> <feComponentTransfer id="svg-4" result="transfer-0"> <feFuncR type="table" id="redChannel-0" tableValues="0.0586, 0.2345, 0.4206, 0.5794, 0.7690, 0.8586, 0.9379"/> </feComponentTransfer> <!--Green curve--> <feComponentTransfer id="svg-5" result="transfer-1"> <feFuncG type="table" id="greenChannel-1" tableValues="0.0000, 0.1655, 0.3620, 0.5414, 0.7138, 0.8413, 1.0000"/> </feComponentTransfer> <!--Blue curve--> <feComponentTransfer id="svg-6" result="transfer-2"> <feFuncB type="table" id="blueChannel-2" tableValues="0.1448, 0.2345, 0.3827, 0.4966, 0.6655, 0.7172, 0.7759"/> </feComponentTransfer> <!--Gamma--> <feComponentTransfer id="b1-3" result="baseimage-3"> <feFuncR type="gamma" id="redChannel-3" amplitude="1.300000" exponent="1.300000" offset="0.000000"/> <feFuncG type="gamma" id="greenChannel-3" amplitude="1.300000" exponent="1.300000" offset="0.000000"/> <feFuncB type="gamma" id="blueChannel-3" amplitude="1.300000" exponent="1.300000" offset="0.000000"/> </feComponentTransfer> <!--Soften-Sharpen--> <feGaussianBlur id="b1-4" result="blurOut-4" in="baseimage-3" stdDeviation="6"/> <feComposite id="c1-4" result="dynResult-4" in="baseimage-3" in2="blurOut-4" operator="arithmetic" k1="0" k2="1.200000" k3="-0.200000" k4="0"/> <!--Spotlight--> <feFlood id="flood-5" result="blackfield-6" x="0%" y="0%" width="100%" height="100%" result="blackfield-6" in="SourceGraphic" flood-color="#000000" flood-opacity="1"/> <feSpecularLighting id="specular-5" result="Spotlight-6" lighting-color="#FFFFFF" surfaceScale="1" specularConstant="1" specularExponent="120"> <fePointLight id="pointlight-5" x="100" y="100" z="854"/> </feSpecularLighting> <feBlend id="svg-7" result="A-6" in="blackfield-6" in2="Spotlight-6" mode="lighten"/> <feBlend id="blend-5" result="B-6" in="A-6" in2="dynResult-4" mode="multiply"/> </filter> </defs> <image id="resultImg" preserveAspectRatio="xMidYMid meet" filter="url(#instagram)" width="100%" height="100%" xlink:href="linktojpeg.jpg"/></svg> 52
  53. 53. Combo Filter: Unsharp MaskTake 2x Original ... Subtract Blur 53 Sharper Version
  54. 54. DEMO: Blur + Original Mix(Photoshop “Unsharp Mask” http://codepen.io/mullany/pen/Hsrof 54
  55. 55. Out of Focus Blur 55
  56. 56. Selective Blur Spotlight + Blur + LumToAlpha +Invert +xor w/original + composite on top of blurredhttp://codepen.io/mullany/pen/mnBqK original 56
  57. 57. <filter id="f1" x="0%" y="0%" width="100%" height="100%"> <feDiffuseLighting result = "diffOut" diffuseConstant = "1" lighting-color = "white"> <feSpotLight id="loc" x = "50" y = "100" z = "150" pointsAtX = "200" pointsAtY = "200" pointsAtZ = "40" specularExponent ="12" limitingConeAngle="20"/> </feDiffuseLighting> <feGaussianBlur in="diffOut" result="blurSpot" stdDeviation="3"/> <feColorMatrix in="blurSpot" result="alphaMap" type="luminanceToAlpha"/> <feComponentTransfer in="alphaMap" result="invertlight"> <feFuncA type="table" tableValues="1 0 0 0"/> </feComponentTransfer> <feComposite operator="xor" result="infocus" in2="SourceGraphic" in="invertlight"/> <feGaussianBlur in="SourceGraphic" result="outfocus" stdDeviation="6"/> <feComposite operator="over" in="infocus" in2="outfocus"/></filter> 57
  58. 58. Edge Booogs & SupportBugs & Missing Features ie moz webkitBackground as input P X XObjects as feImage input ? X XFill & stroke paint as input P X XColor space interpolation P P (not safari)Correct lightsource positions P P X<animate> support X P PFilter references ? ? XCorrect default filter resolution P P (not safari) 58
  59. 59. “Why does my filter effect look clipped?” “Why is the filter overflowing my content?”Filter region defaults: -10%, -10%, 120%, 120% 59
  60. 60. Next Steps‣ Spec ‣ http://www.w3.org/TR/SVG/filters.html‣ Inkscape Filter Samples ‣ http://inkscape.org‣ Webplatform documentation ‣ First draft: http://docs.webplatform.org/ wiki/svg/elements/filter 60
  61. 61. THANK YOU!!michael aat sencha.com 61

×