W3C

SVG Filters 1.2, Part 1: Primer

W3C Editor’s Draft 07 January 2011

This version:
http://dev.w3.org/SVG/modules/filters/publish/SVGFilterPrimer.html
Latest version:
http://www.w3.org/TR/SVGFilterPrimer12/
Previous version:
http://www.w3.org/TR/2007/WD-SVGFilterPrimer12-20070501/
Editor:
Erik Dahlström, Opera Software <ed@opera.com>
Authors:
The authors of this specification are the participants of the W3C SVG Working Group.

Abstract

SVG is language for describing vector graphics, however it's typically rendered on raster displays. SVG filter effects is a way of processing the generated raster image before it's displayed.

Although originally designed for use in SVG, filter effects are defined in XML and are accessed via a presentation property, and therefore could be used in other environments, such as HTML styled with CSS and XSL:FO.

This document introduces the features used by SVG filters.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. The latest status of this document series is maintained at the W3C.

This document is the first public working draft of this specification.

This document has been produced by the W3C SVG Working Group as part of the W3C Graphics Activity within the Interaction Domain.

We explicitly invite comments on this specification. Please send them to public-svg-filters@w3.org (archives). For comments on the core SVG language, use www-svg@w3.org: the public email list for issues related to vector graphics on the Web (archives). Acceptance of the archiving policy is requested automatically upon first post to either list. To subscribe to these lists send an email to public-svg-filters-request@w3.org or www-svg-request@w3.org with the word subscribe in the subject line.

The latest information regarding patent disclosures related to this document is available on the Web. As of this publication, the SVG Working Group are not aware of any royalty-bearing patents they believe to be essential to SVG.

Publication of this document does not imply endorsement by the W3C membership. A list of current W3C Recommendations and other technical documents can be found at http://www.w3.org/TR/. W3C publications may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to cite a W3C Working Draft as anything other than a work in progress."

How to read this document and give feedback

This is a primer for the SVG Filter specification. It gives guidelines on how to use the SVG Filter specification with SVG 1.2. In many cases the reader will have to be familiar with the SVG language.

This document is informative.

Table of Contents

1 Filters in SVG

Filter effects are defined by ‘filter’ elements. To apply a filter effect to a graphics element or a container element, you set the value of the ‘filter’ property on the given element such that it references the filter effect.

Each ‘filter’ element contains a set of filter primitives as its children. Each filter primitive performs a single fundamental graphical operation (e.g., a blur or a lighting effect) on one or more inputs, producing a graphical result. Because most of the filter primitives represent some form of image processing, in most cases the output from a filter primitive is a single RGBA image.

The original source graphic or the result from a filter primitive can be used as input into one or more other filter primitives. A common application is to use the source graphic multiple times. For example, a simple filter could replace one graphic by two by adding a black copy of original source graphic offset to create a drop shadow. In effect, there are now two layers of graphics, both with the same original source graphics.

When applied to container elements such as ‘g’, the ‘filter’ property applies to the contents of the group as a whole. The group's children do not render to the screen directly; instead, the graphics commands necessary to render the children are stored temporarily. Typically, the graphics commands are executed as part of the processing of the referenced ‘filter’ element via use of the keywords SourceGraphic or SourceAlpha. Filter effects can be applied to container elements with no content (e.g., an empty ‘g’ element), in which case the SourceGraphic or SourceAlpha consist of a transparent black rectangle that is the size of the filter effects region.

Sometimes filter primitives result in undefined pixels. For example, filter primitive ‘feOffset’ can shift an image down and to the right, leaving undefined pixels at the top and left. In these cases, the undefined pixels are set to transparent black.

2 An example

The following shows an example of a filter effect.

Example filters01 - introducing filter effects.

<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" 
              "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="7.5cm" height="5cm" viewBox="0 0 200 120"
     xmlns="http://www.w3.org/2000/svg" version="1.1">
  <title>Example filters01.svg - introducing filter effects</title>
  <desc>An example which combines multiple filter primitives
        to produce a 3D lighting effect on a graphic consisting
        of the string "SVG" sitting on top of oval filled in red
        and surrounded by an oval outlined in red.</desc>
  <defs>
    <filter id="MyFilter" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120">
      <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
      <feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
      <feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75" 
                          specularExponent="20" lighting-color="#bbbbbb"  
                          result="specOut">
        <fePointLight x="-5000" y="-10000" z="20000"/>
      </feSpecularLighting>
      <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
      <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
                   k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
      <feMerge>
        <feMergeNode in="offsetBlur"/>
        <feMergeNode in="litPaint"/>
      </feMerge>
    </filter>
  </defs>
  <rect x="1" y="1" width="198" height="118" fill="#888888" stroke="blue" />
  <g filter="url(#MyFilter)" >
	  <g>
      <path fill="none" stroke="#D90000" stroke-width="10" 
            d="M50,90 C0,90 0,30 50,30 L150,30 C200,30 200,90 150,90 z" />
      <path fill="#D90000" 
            d="M60,80 C30,80 30,40 60,40 L140,40 C170,40 170,80 140,80 z" />
      <g fill="#FFFFFF" stroke="black" font-size="45" font-family="Verdana" >
        <text x="52" y="76">SVG</text>
      </g>
    </g>
  </g>
</svg>
Example
Example

View this example as SVG (SVG-enabled browsers only)

The filter effect used in the example above is repeated here with reference numbers in the left column before each of the six filter primitives:

 
 
1
2
3
 
 
 
 
4
5
 
6
 
 
 
<filter id="MyFilter" filterUnits="userSpaceOnUse" x="0" y="0" width="200" height="120">
  <desc>Produces a 3D lighting effect.</desc>
  <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
  <feOffset in="blur" dx="4" dy="4" result="offsetBlur"/>
  <feSpecularLighting in="blur" surfaceScale="5" specularConstant=".75" 
                      specularExponent="20" lighting-color="#bbbbbb" 
                      result="specOut">
    <fePointLight x="-5000" y="-10000" z="20000"/>
  </feSpecularLighting>
  <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
  <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
               k1="0" k2="1" k3="1" k4="0" result="litPaint"/>
  <feMerge>
    <feMergeNode in="offsetBlur"/>
    <feMergeNode in="litPaint"/>
  </feMerge>
</filter>

The following pictures show the intermediate image results from each of the six filter elements:

filters01 - original source graphic
Source graphic

 

filters01 - after filter element 1
After filter primitive 1

 

filters01 - after filter element 2
After filter primitive 2

 

filters01 - after filter element 3
After filter primitive 3

  
  

filters01 - after filter element 4
After filter primitive 4

 

filters01 - after filter element 5
After filter primitive 5

 

filters01 - after filter element 6
After filter primitive 6

  1. Filter primitive ‘feGaussianBlur’ takes input SourceAlpha, which is the alpha channel of the source graphic. The result is stored in a temporary buffer named "blur". Note that "blur" is used as input to both filter primitives 2 and 3.
  2. Filter primitive ‘feOffset’ takes buffer "blur", shifts the result in a positive direction in both x and y, and creates a new buffer named "offsetBlur". The effect is that of a drop shadow.
  3. Filter primitive ‘feSpecularLighting’, uses buffer "blur" as a model of a surface elevation and generates a lighting effect from a single point source. The result is stored in buffer "specOut".
  4. Filter primitive ‘feComposite’ masks out the result of filter primitive 3 by the original source graphics alpha channel so that the intermediate result is no bigger than the original source graphic.
  5. Filter primitive ‘feComposite’ composites the result of the specular lighting with the original source graphic.
  6. Filter primitive ‘feMerge’ composites two layers together. The lower layer consists of the drop shadow result from filter primitive 2. The upper layer consists of the specular lighting result from filter primitive 5.

3 Filter primitive ‘feGaussianBlur’

The ‘feGaussianBlur’ filter primitive can be used to create blur effects. Below is an example where the blur is applied only in one direction, which can give better performance in some user agents.

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 480 360">
  <defs>
    <font-face font-family="FORQUE">
      <font-face-src>
        <font-face-uri xlink:href="Forque.svg#FORQUE"/>
      </font-face-src>
    </font-face>
    <style>
      /* Free font by Tup Wanders, http://www.tupwanders.nl, Licensed with a Creative Commons attribution license. */
      text { text-anchor: middle; font: 70px FORQUE, sans-serif; }
      #bx { filter: url(#blurX) }
      #by { filter: url(#blurY) }
      #header { filter: url(#ds); fill: white; text-decoration: underline }
      #attribution { font-size: 6px }
      :root { background: green; fill: white }
    </style>
    <filter id="blurX" x="0" y="20%" width="100%" height="1.5em" filterUnits="userSpaceOnUse">
      <feGaussianBlur stdDeviation="4 0">
        <animate attributeName="stdDeviation" values="8 0;20 0;0 0" keySplines="0.25 0.1 0.25 1" keyTimes="0;0.5;1" calcMode="spline" dur="4s" begin="bx.click" fill="freeze"/>
      </feGaussianBlur>
    </filter>
    <filter id="blurY" x="0" y="0" width="100%" height="100%" filterUnits="userSpaceOnUse">
      <feGaussianBlur stdDeviation="0 4"/>
    </filter>
    <filter id="ds" x="-0.1" y="-0.1" width="1.2" height="1.2">
      <feGaussianBlur stdDeviation="3"/>
      <feOffset dx="2" dy="2"/>
      <feComposite in2="SourceGraphic" operator="in"/>
    </filter>
  </defs>

  <text id="bx" x="40%" y="50%">BlurX</text>
  <text id="by" x="60%" y="70%">BlurY</text>
  
  <text id="header" y="1em" x="50%">Unidirectional blur</text>
  <text id="attribution" x="100%" y="355">Forque font by Tup Wanders</text>
</svg>
Example
Example

View this example as SVG (SVG-enabled browsers only)

The blur filter can also be used for creating the impression of something being in motion, as in this example.

<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 480 360">
  <defs>
    <filter id="motionblur" filterUnits="userSpaceOnUse">
      <feGaussianBlur stdDeviation="5 0"/>
    </filter>
    <symbol id="crow" viewBox="0 0 197 190">
      <path d="M 72.566789,186.38448 C 71.202549,184.36785 66.167569,175.06788 61.377949,165.71788 C 56.588329,156.36788 52.650829,149.03965 52.627949,149.43293 C 52.605069,149.82621 53.231819,152.07621 54.020719,154.43293 C 56.134749,160.74826 59.591199,174.77158 59.554549,176.88449 C 59.524869,178.59503 59.416409,178.58387 57.935879,176.71788 C 55.201299,173.27137 45.853349,153.1995 41.635529,141.71788 C 37.663679,130.90581 37.605079,130.81611 38.205719,136.46788 C 38.959899,143.56439 37.583169,143.96813 34.795769,137.46788 C 30.104179,126.52701 28.892829,118.89987 27.609109,92.21788 C 26.579279,70.81278 27.181269,61.74079 30.007419,56.07564 C 31.906109,52.26963 32.139109,52.60152 20.824699,42.99574 C 13.205099,36.52681 11.734279,35.68694 7.1852392,35.20738 L 2.0863492,34.66985 L 7.5863492,32.82094 C 10.611349,31.80405 13.481709,30.60949 13.964929,30.16638 C 15.394959,28.85504 9.7899892,24.44625 4.4291292,22.66566 C 1.6943392,21.75731 -0.28374076,20.75464 0.033389242,20.43751 C 0.35051924,20.12038 7.2421692,19.78442 15.348169,19.69093 C 30.881569,19.51179 34.937409,20.13958 47.086349,24.60361 C 50.936349,26.01826 55.713159,27.18519 57.701489,27.19679 C 65.982349,27.2451 71.556499,17.90344 69.368439,7.6442896 C 67.940739,0.95023961 69.214399,0.010319613 79.726899,2.961339e-05 C 85.523249,-0.0056403866 91.246029,0.80265961 98.391539,2.6362896 C 104.0594,4.0907296 112.29453,5.9632196 116.69184,6.7973796 C 134.01279,10.0831 145.35739,15.11226 132.4653,13.78988 C 123.72653,12.89352 125.97985,14.08978 145.54774,20.73521 C 161.35384,26.10311 174.7538,32.06177 176.16916,34.35187 C 176.71697,35.23824 175.39586,35.37836 170.91088,34.90959 C 167.61644,34.56525 164.05819,34.00702 163.00367,33.66907 C 159.44558,32.52878 164.45052,35.98642 172.8528,40.47328 C 181.01437,44.83161 187.58635,49.6841 187.58635,51.35196 C 187.58635,51.95969 185.75677,52.07923 182.83635,51.6623 C 177.61881,50.91742 177.61253,50.9017 184.83635,56.66751 C 189.29595,60.22701 191.15689,64.23449 188.33635,64.20466 C 187.64885,64.19739 183.75408,62.28489 179.6813,59.95466 C 175.60852,57.62443 170.43352,54.66077 168.1813,53.36875 C 160.24766,48.81749 155.25808,48.53915 153.96805,52.57585 C 153.59155,53.75397 153.17397,57.05515 153.04009,59.91181 C 152.72526,66.62933 148.47286,73.16418 144.39537,73.19653 C 141.27521,73.22129 140.06261,74.55103 141.84736,75.99069 C 143.5779,77.38662 163.91595,85.24612 177.08635,89.60855 C 183.13635,91.61249 189.88635,94.27223 192.08634,95.51908 C 196.03044,97.75438 196.08764,97.86951 196.17774,103.75198 C 196.32804,113.55263 191.83044,119.99235 183.2058,122.3255 C 179.71567,123.26966 178.08026,123.11668 172.50059,121.32412 C 165.62068,119.11384 161.59126,116.76556 147.7546,106.9026 C 143.17214,103.63615 137.09714,100.07812 134.2546,98.99585 L 129.08635,97.0281 L 124.58635,102.12335 C 122.11135,104.92574 119.27183,107.21844 118.2763,107.21824 C 117.28078,107.21804 114.25803,108.66351 111.55908,110.4304 C 108.02382,112.74478 106.47184,114.49211 106.00784,116.6804 C 105.6536,118.35101 104.7976,120.39288 104.10563,121.21788 C 102.12794,123.57575 99.866059,134.66955 99.008439,146.21788 C 98.702099,150.34288 97.981489,154.68231 97.407089,155.86106 C 96.606229,157.50454 96.855109,159.32029 98.474539,163.64858 C 99.636029,166.75296 100.58635,170.19015 100.58635,171.28678 C 100.58635,174.34075 97.802589,174.76966 95.009829,172.14599 L 92.535069,169.82107 L 94.060709,174.1452 C 97.730759,184.54723 95.140999,185.2202 87.992199,175.72216 C 84.864209,171.56625 82.136779,168.33411 81.931259,168.53964 C 81.725729,168.74517 82.756989,171.5332 84.222939,174.73527 C 87.061249,180.93494 87.859979,187.23913 85.894459,187.92805 C 85.215209,188.16613 81.485349,182.83448 77.222469,175.53184 C 73.108409,168.48416 69.042179,161.81788 68.186409,160.71788 C 66.764029,158.88956 66.749579,159.06125 68.018079,162.71788 C 68.781269,164.91788 70.803819,170.06041 72.512649,174.14572 C 77.734689,186.63018 77.767619,194.07236 72.566789,186.38448 z"/>
    </symbol>
  </defs>
  
  <image xlink:href="forest-small.jpg" width="100%" height="100%" filter="url(#motionblur)"/>
  <use xlink:href="#crow" width="25%" height="25%" x="20%" y="40%" transform="rotate(-12)"/>
   
</svg>
Example
Example

View this example as SVG (SVG-enabled browsers only)

4 References

SVG12
Scalable Vector Graphics (SVG) 1.2 Specification, Dean Jackson editor, W3C, 27 October 2004 (Working Draft). See http://www.w3.org/TR/2004/WD-SVG12-20041027/
SVG12Reqs
SVG 1.1/1.2/2.0 Requirements, Dean Jackson editor, W3C, 22 April 2002 (Working Draft). See http://www.w3.org/TR/2002/WD-SVG2Reqs-20020422/
SVGFilterReqs
SVG Filter Requirements, Erik Dahlström, W3C, 3 May 2007 (Working Draft). See http://www.w3.org/TR/2007/WD-SVGFilterReqs12-20070501/
SVG12Filters
SVG Filters 1.2, Erik Dahlström editor, W3C, 3 May 2007 (Working Draft). See http://www.w3.org/TR/2007/WD-SVGFilter12-20070501/