Web Info and IT Lessons Blog...

Tuesday 14 April 2015

SVG Filter Effects

The previous lesson of svg lessons series was about SVG Text Element and in this lesson we will learn to apply filter to an svg element.

SVG Filter Effects

When applying filter to an svg element we need to pass the source element through a series of graphic operations to get the desired filtered results. The operations we need to perform to get the filtered results are as follows:

1. GaussianBlur (feGaussianBlur)
2. Offset (feOffset)
3. SpecularLighting (feSpecularLighting)
4. Composite (feComposite)
5. Merge (feMerge)

Let us see the effects of each of these operations individually by applying to a rectangle. An svg rectangle is given below:


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="200" height="100" rx="10" ry="10" fill="green" />
</svg>

GaussianBlur (feGaussianBlur)


Let us apply blur effect to the above rectangle i.e


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<def>
<filter id="MyFilter" filterUnits="userSpaceOnUse" x="0%" y="0%" width="100%" 
height="100%">
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"/>
</filter>
</def>
<rect width="200" height="100" filter="url(#MyFilter)" rx="10" ry="10" fill="green" />
</svg>

In the above svg code a filter with id="MyFilter" is defined inside the tag. The operations performed in the filter is only GuassianBlur effect. The defined filter is then applied to the rectangle using filter="url(#MyFilter)". You can see in the above image the effect of GuassianBlur is a black blur image. This is because the input passed in the GuassianBlur operation is black version of the rectangle i.e (in="SourceAlpha"), if we want to GuassianBlur to apply to the same red rectangle, we need to pass (in="SourceGraphic") in it.


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<def>
<filter id="MyFilter2" filterUnits="userSpaceOnUse" x="0%" y="0%" width="100%" 
height="100%">
<feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"/>
</filter>
</def>
<rect width="200" height="100" filter="url(#MyFilter2)" rx="10" ry="10" fill="green" />
</svg>

The amount of blur depends upon the value of standard deviation (i.e stdDeviation). Increasing the value of standard deviation increases the blur effect and vice versa.

Offset (feOffset)



<feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>

Offset operation is used to move the image passed in it as input in x and y direction by the values specified in dx and dy. You can see in the above offset code the input of offset operation is the result of GuassianBlur operation. This means that feOffset will move the blur image by 2px in both x and y directions.

SpecularLighting (feSpecularLighting)


feSpecularLighting uses blur to decide the lighting effect. The input of feSpecularLighting is the result of GaussianBlur i.e result="blur"


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<def>
<filter id="MyFilter3" filterUnits="userSpaceOnUse" x="0%" y="0%" width="100%" 
height="100%">
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"/>
<feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
<feSpecularLighting in="blur" surfaceScale="5" specularConstant=".80" 
    specularExponent="20" lighting-color="#bbbbbb"  
    result="lightingOut">
 <fePointLight x="-5000" y="-10000" z="20000"/>
</feSpecularLighting>
</filter>
</def>
<rect width="200" height="100" filter="url(#MyFilter3)" rx="10" ry="10" fill="green" />
</svg>

Composite (feComposite)



<feComposite in="lightingOut" in2="SourceAlpha" operator="in" result="lightingOut"/>

feComposite takes two inputs in="lightingOut" and in2="SourceAlpha". One input is the result of feSpecularLighting and other input is the original source alpha channel image. This step is used to mask out the result of feSpecularLighting with the original source alpha channel image to ensure that the result image is not large than the original source image. The operator="in" specified above means the result of in="lightingOut" within the boundaries of in2="sourceAlpha".


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<def>
<filter id="MyFilter4" filterUnits="userSpaceOnUse" x="0%" y="0%" width="100%" 
height="100%">
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"/>
<feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
<feSpecularLighting in="blur" surfaceScale="5" specularConstant=".80" 
        specularExponent="20" lighting-color="#bbbbbb"  
        result="lightingOut">
  <fePointLight x="-5000" y="-10000" z="20000"/>
</feSpecularLighting>
<feComposite in="lightingOut" in2="SourceAlpha" operator="in" result="lightingOut"/>
</filter>
</def>
<rect width="200" height="100" filter="url(#MyFilter4)" rx="10" ry="10" fill="green" />
</svg>

Now we need to perform feComposite operation one more time with in="SourceGraphic", in2="lightingOut" and operator="arithmetic".


<feComposite in="SourceGraphic" in2="lightingOut" operator="arithmetic" 
k1="0" k2="1" k3="1" k4="0" result="compositeOut"/>

This operation will add the lighting effect to the original source image (not the alpha version).


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<def>
<filter id="MyFilter5" filterUnits="userSpaceOnUse" x="0%" y="0%" width="100%" 
height="100%">
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"/>
<feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
<feSpecularLighting in="blur" surfaceScale="5" specularConstant=".80" 
        specularExponent="20" lighting-color="#bbbbbb"  
        result="lightingOut">
  <fePointLight x="-5000" y="-10000" z="20000"/>
</feSpecularLighting>
<feComposite in="lightingOut" in2="SourceAlpha" operator="in" result="lightingOut"/>
<feComposite in="SourceGraphic" in2="lightingOut" operator="arithmetic" 
k1="0" k2="1" k3="1" k4="0" result="compositeOut"/>
</filter>
</def>
<rect width="200" height="100" filter="url(#MyFilter5)" rx="10" ry="10" fill="green" />
</svg>

Merge (feMerge)


In the end all we need to do is perform the merge operation on the result of feOffset and feComposite i.e


<feMerge>
<feMergeNode in="offsetBlur"/>
<feMergeNode in="compositeOut"/>
</feMerge>


<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<def>
<filter id="MyFilter6" filterUnits="userSpaceOnUse" x="0%" y="0%" width="100%" 
height="100%">
<feGaussianBlur in="SourceAlpha" stdDeviation="5" result="blur"/>
<feOffset in="blur" dx="2" dy="2" result="offsetBlur"/>
<feSpecularLighting in="blur" surfaceScale="5" specularConstant=".80" 
        specularExponent="20" lighting-color="#bbbbbb"  
        result="lightingOut">
<fePointLight x="-5000" y="-10000" z="20000"/>
</feSpecularLighting>
<feComposite in="lightingOut" in2="SourceAlpha" operator="in" result="lightingOut"/>
<feComposite in="SourceGraphic" in2="lightingOut" operator="arithmetic" 
k1="0" k2="1" k3="1" k4="0" result="compositeOut"/>
<feMerge>
<feMergeNode in="offsetBlur"/>
<feMergeNode in="compositeOut"/>
</feMerge>
</filter>
</def>
<rect width="200" height="100" filter="url(#MyFilter6)" rx="10" ry="10" fill="green" />
</svg>

Stay tuned for more lessons...

Related Posts
Draw a glowing lamp using SVG
Drawing Paths in SVG
Drawing a cup using SVG Path Element
SVG Text Element And Attributes
Basics of SVG Graphics

No comments:

Post a Comment