An Inkscape SVG Filter Tutorial — Part 2

Part 1 introduced SVG filter primitives and demonstrated the creation of a Fabric filter effect. Part 2 shows various ways to colorize the fabric. It ends with an example of using the techniques learned here to draw part of a bag of coffee beans.

Dying the Fabric

Our fabric at this point is white. We can give it color a variety of ways. We could have started off with a colorized pattern but that would not allow us to change the color so easily. And as this is a tutorial on using filters, lets look at ways the color can be changed utilizing filter primitives.

Coloring with the Flood, Blend, and Composite Primitives

We can use the Flood filter primitive to create a sheet of solid color and then use the Blend filter primitive to combine it with the fabric. The resulting image bleeds into the background. We’ll use the Composite filter primitive to auto-clip the background.

The Flood Filter Primitive

Add the Flood filter primitive to the filter chain by selecting Flood and clicking on the Add Effect button. The fabric will turn a solid black. Like the Turbulence filter primitive, the Flood filter primitive takes no inputs but simply fills the filter region with a solid color Black is the default flood color. You can change the color by clicking on the color sample next to Flood Color: in the dialog. Change the color however you wish. Leave the Opacity at one.

The Blend Filter Primitive.

Next add the Blend filter primitive. The drawing will be unchanged. Connect the Blend input to the last Displacement Map. The fabric should appear on top of the flood fill. This is expected as the default blending mode is Normal which simply draws the second image over the first. Use the drop-down menu to change the Mode to Multiply. This results in the lighter areas of the fabric taking on the flood color.

The output of the filter chain after blending.

Try experimenting with the other blending modes.

The Composite Filter Primitive

The flood fill leaks into the background. This can be removed by clipping the image to fabric area using the Composite filter primitive. Add the Composite filter primitive to the filter chain. The resulting image is again unchanged. Connect the second input to the composite filter to the last Displacement Map filter primitive. Still the image remains unchanged. Now change the Operator type to In. This dictates that the image should be clipped to the area that is “In” the image created by the second Displacement Map filter primitive.

Filter Dialog image.

The Filter Effect dialog after adding and adjusting the Flood, Blend, and Composite filter primitives.

The output of the filter after compositing.

Coloring the Fabric with the Component Transfer Filter Primitive

The Component Transfer filter primitive maps, pixel by pixel, the colors from an input image to different colors in an output image. Each “component” (Red, Green, Blue, and Alpha) is mapped independently. The method for mapping is determined by the Type; each Type has its own attributes. We’ll use the Linear and Identity mappings.

Identity
The output component has the same value as the input component.
Linear
The output component is equal to: intercept + input × slope. This is identical to the Identity type if the intercept is zero and the slope is one.

Replace the Flood Fill, Blend, and Composite filter primitives in the above filter chain by the Composite Transfer filter primitive. (To delete a filter primitive, right-click on the filter primitive name and select Delete in the menu that appears.) The just removed three-primitive filter chain mapped black to black and white to the flood color. We can duplicate this by setting the Red, Green, and Blue component transfer types to Linear (keeping the Alpha component type set to Identity). The condition that black maps to black requires that the Intercept values all be set to zero. The condition that white maps to the flood color dictates the slopes. The RGB values for the flood color used above are 205, 185, 107 on a scale where 255 is the maximum value. These values translate to 0.80, 0.73, 0.42 on a scale where the maximum value is one. Since an input value of 1.0 for the red component must result in a value of 0.80 we can see that these values are the required slopes.

Graph of input vs. output for the red, green, and blue channels.

Graph of the transfer functions.

Filter Dialog image.

The Filter Effect dialog after adding and adjusting the Component Transfer filter primitive.

The output of the filter after adding and adjusting the Component Transfer filter primitive.

Now suppose we want the fabric to be more subtle. We can change the mapping so that for each component, zero is mapped to half the maximum value. In this case we have the following values (RGB): Intercepts: 0.40, 0.36, 0.21 and Slopes: 0.40, 0.37, 0.21. See the following figure:

Graph of input vs. output for the red, green, and blue channels.

Graph of the transfer functions where the darkest value is half the lightest value.

Filter Dialog image.

The Filter Effect dialog after adding and adjusting the Component Transfer filter primitive.

The output of the filter after adjusting the Component Transfer filter primitive so the darkest areas have half the component values of the lightest.

Coloring the Fabric with the Color Matrix Filter Primitive

This filter primitive, unlike the Component Transfer, can intermix the color components. It does not, however, have the fine control over the transfer curves like in the Component Transfer filter primitive. There are several Types in this filter primitive. The Saturate, Hue Rotate, and Luminous to Alpha types are shortcuts for the more generic Matrix type. We need to use the Matrix type to match the results of the previous filters.

First replace the Component Transfer filter primitive by the Color Matrix filter primitive. After adding the new primitive, the fabric may disappear; that is a bug in Inkscape. Click on the matrix in the Filter Dialog and the fabric should reappear. The initial matrix is the Identity matrix (consisting of ones on the diagonal) which does not change the image.

The rows in the matrix control the output of, from top to bottom, the Red, Green, Blue, and Alpha channels. The columns correspond to the input, again in the same Red, Green, Blue, and Alpha order. The last column allows one to enter a constant offset for the row. For example, one can make a green object red by changing the top row to “0 1 0 0 0″ which means that the Red channel output is 0×R + 1×G + 0×B + 0×A + 0, where R, G, B, and A are the input values for the Red, Green, Blue, and Alpha channels respectively (on a scale of zero to one).

To change the values in the matrix, click first on a row of numbers to select the row and then click on a numeric entry in the row. The following figures show the values needed to match the fabric samples above.

Filter Dialog image.

The Filter Effect dialog after adding and adjusting the Color Matrix filter primitive to match the first (high contrast) fabric sample above.

Filter Dialog image.

The Filter Effect dialog after adding and adjusting the Color Matrix filter primitive to match the second (lower contrast) fabric sample above.

Coloring the Fabric Using the Fill Color and the Tile Filter Primitive

In an ideal world, a fabric filter would just take as input the color of an object and use that to blend with a pattern. SVG filters do have the ability to do this. One would read in a pattern tile using the Image filter primitive and then tile the pattern using the Tile filter primitive. But the Tile filter primitive is the one filter primitive that Inkscape hasn’t implemented. While more convenient, this method would still lack the fine control over color that the above methods have.

The output of a filter using the Tile primitive. The two rectangles differ only in Fill color. Renders correctly in Chrome, incorrectly in Firefox and Inkscape.

Putting it All Together

Let’s do something with the fabric! We could stencil some text on the fabric to make it look like part of a bag of coffee beans. The best way to do this is to break the filter up into two separate filters. The first will distort the weave (using the first Turbulence and Displacement Map pair and color the fabric while the second will add a gentle wave to both the fabric and text (using the second Turbulence and Displacement Map pair). The text is given its own filter to take away the sharp edges and to also give it a bit of irregularity independent of the weave. The text could be blended on top of the fabric by giving it an opacity of less than one. A better effect can be achieved, however, by using the new mix-blend-mode property. Inkscape can render this property but does not yet have a GUI to set it. Firefox supports this property and Chrome should soon (if it doesn’t already). I’ve used the mix-blend-mode value of multiply by adding the property to the text style attribute with the XML editor. The fabric and text are then grouped together before applying the “wave” filter to the group.

Part of a bag of coffee beans. Three filters are used. The first to distort the weave and give color to the fabric, the second to slightly blur and distort the text, and the third to take the blended together fabric and text and give them both a gentle wave.

Note, it is possible to put the text in the “defs” section and use the Image filter primitive to import the text into a filter so that the blending can be done with the Blend filter primitive. This isn’t easy to do in Inkscape and Firefox seems to have problems rendering it.

I hope you enjoyed this tutorial. Please leave comments and questions!


A section of a bag of coffee beans.

A PNG image just for Google+ which doesn’t support SVG images.

An Inkscape SVG Filter Tutorial — Part 1

Part 1 introduces SVG filter primitives and demonstrates the creation of a Fabric filter effect. Part 2 shows various ways to colorize the fabric.

Introduction

SVG filters allow bitmap-type manipulations inside a vector format. Scalability is preserved by pushing the bitmap processing to the SVG renderer at the point when the final screen resolution is known. SVG filters are very powerful, so powerful in fact that they have been moved out of SVG and into a separate CSS specification so that they can also be applied to HTML content. This power comes with a price: SVG filters can be difficult to construct. For example, a simple drop shadow filter consists of three connected filter primitives as shown in this SVG code:
<filter id="DropShadow">
  <feOffset in="SourceAlpha" dx="2" dy="2" result="offset"/>  ❶
  <feGaussianBlur in="offset" stdDeviation="2" result="blur"/>  ❷
  <feBlend in="SourceGraphic" in2="blur" mode="normal"/>  ❸
 </filter>
  1. Offset filter primtive: Create an image using the text alpha (SourceAlpha) and shift it down and right two pixels. Results in shifted black text.
  2. Gaussian Blur filter primitive: Blur result of previous step (“offset”).
  3. Blend filter primtive: Render the original image (SourceGraphic) over the result of the previous step (“blur”).
Some sample text!

A drop shadow applied to text.

Inkscape contains a Filter Dialog that can be used to construct filters. Here is the dialog showing the above drop-shadow filter effect:

Filter dialog showing the three filter primitives and how they are connected.

The Inkscape Filter Dialog showing a drop-shadow filter effect. The dialog shows the filter primitives and how their inputs (left-pointing triangles) are connected (black lines). It also contains controls for setting the various filter primitive attributes.

There can be more than one way to construct the same filter effect. For example, the order of the offset and blur primitives can be swapped without changing the result:

Some more text!

An alternative drop-shadow filter applied to text.

Inkscape contains over 200 canned filters effects, many of which have adjustable parameters. But sometimes none of them will do exactly what you want. In that case you can construct your own filter effect. It’s not as hard as it first seems once you understand some of the basic filter primitives.

A Fabric Filter

This tutorial creates a basic filter that can be applied to a pattern to create realistic fabric. It will introduce several very useful filter primitives that are fundamental to most of Inkscape’s canned filter effects.

Creating a Pattern

To begin with, we need a pattern that is the basis of the weave of the fabric. I’ve constructed a simple pattern consisting of four rectangles, two for the horizontal threads and two for the vertical threads. I’ve applied a linear gradient to give them a 3D look. One can certainly do better but as the pattern tile is quite small, one need not go overboard. Once you have drawn all the pattern parts, select them and then use Objects->Pattern to convert to a pattern. The new pattern will then be available in the Pattern drop-down menu that appears when the Pattern icon is highlighted on the Fill tab of the Fill and Stroke dialog.

The pattern consisting of four rectangles with linear gradients simulating a small section of the fabric weave.

The pattern (shown scaled up).

Next, apply the fabric pattern to the an object to create simple fabric.

The basic weave pattern applied to a large rectangle.

The pattern applied to a large rectangle.

Adding Blur

The pattern looks like a brick wall. It’s too harsh for fabric. We can soften the edges by applying a little blur. This is done through the Gaussian Blur filter primitive. Open the Filter Editor dialog (Filters->Filter Editor). Click on the New button to create a new, empty filter. A new filter with the name “filter1″ should be created. You can double click on the name to give the filter a custom name. Apply the filter to the fabric piece by selecting the piece and then checking the box next to the filter name. Your piece of fabric will disappear; don’t worry. We need to add a filter primitive to get it to show back up. To add a blur filter primitive select Gaussian Blur in the drop-down menu next to Add Effect and then clicking the Add Effect button. The fabric should now be visible with the blur effect applied. You can change the amount of blur by using the slider next to Standard Deviation; a value of 0.5 seems to be about right.

Filter Dialog image.

The Filter Effect dialog after applying a small amount of blur.

Note how the input to the Gaussian Blur primitive (triangle next to “Gaussian Blur”) is linked (under Connections) to the Source Graphic.
The basic weave pattern applied to a large rectangle.

A small amount of blur applied to the fabric.

Distorting the Threads

The pattern is still too rigid. The threads in real fabric are not so regular looking. We need to add some random distortions. To do so, we’ll link up two different filter primitives. The first filter primitive, Turbulence, will generate random noise. This noise will be used as an input to a Displacement Map filter primitive where pixels are shifted based on the value of the input.

The Turbulence Filter Primitive

Add a Turbulence filter primitive to the filter chain by selecting Turbulence from the drop-down menu next to Add Effect button, the click on the button. You should see a rectangle region filled with small random dots. There are a couple of things to note: The first is that the rectangle will be bigger than you initial object. This is normal. The filter region is enlarged by 10% on each side and the Turbulence filter fills this region. This is done on purpose as some filter primitives draw outside the object (e.g. the Gaussian Blur and Offset primitives). You can set the boundary of the filter region under the Filter General Settings tab. The default 10% works for most filters. You don’t want the region to be too large as it effects the time to render the filter. The second thing to note is that the Turbulence filter primitive has no inputs despite what is shown in the Filter Editor dialog.

There are a number of parameters to control the generation of the noise:

Type
There are two values: Turbulence and Fractal Noise. The difference between the two is somewhat technical so I won’t go into it here. (See the Turbulence Filter Primitive section in my guide book.)
Base Frequency
This parameter controls the granularity of the noise. The value roughly corresponds to the inverse of the length in pixels of the fluctuations. (Note that the default value of ‘0’ is a special case and doesn’t follow this rule.)
Octaves
The number of octaves used in creating the turbulence. For each additional octave, a new contribution is added to the turbulence with the frequency doubled and the contribution halved compared to the proceeding octave. It is usually not useful to use a value above three or four.
Seed
The seed for the pseudo-random number generator used to create the turbulence. Normally one doesn’t need to change this value.

One can guess that variations in the threads are about on the order of the distance between adjacent threads. For the pattern used here, the vertical threads are 6 pixels apart. This gives a base frequency of about 0.17 (i.e. 1/6). The value of Type should be changed to Fractal Noise. (Both Type values give good visual results but the Turbulence value leads to a shift of the image down and to the right for technical reasons.) Here is the resulting dialog:

Filter Dialog image.

The Filter Effect dialog after adding the Turbulence filter primitive.

And here is the resulting image:

The output of the first turbulence filter primitive.

The output of the filter chain which is at this point the output of the Turbulence filter primitive.

The Displacement Map Filter Primitive

Now we need to add the Displacement Map filter primitive which will take both the output of the Gaussian Blur and the Turbulence filter primitives as inputs. Select Dispacement Map from the drop-down menu and then click on the Add Effect button. Note that both inputs to the Dispacement Map filter primitive are set to the last filter primitive in the filter chain. We’ll need to drag the top one to the Gaussian Blur filter primitive. (Start the drag in the little triangle at the right of the filter primitive in the list.) Again, the image doesn’t change. We’ll need to make one more change but first here are the parameters for the Displacement Map filter primitive:

Scale
The scale factor is used to determine how far pixels should be shifted. The magnitude of the shift is the value of the displacement map (on a scale of 0 to 1) multiplied by this value.
X displacment
Determines which component (red, green, blue, alpha) should be used from the input map to control the x displacement.
Y displacement
Determines which component (red, green, blue, alpha) should be used from the input map to control the y displacement.

For our purpose, any values of X displacement and Y displacement are equally valid as all channels contain the same type of pseudo-random noise. To actually see a shift, one must set a non-zero scale factor. A value of about six seems to give a good effect.

Filter Dialog image.

The Filter Effect dialog after adding and adjusting the Displacement Map filter primitive.

And here is the resulting image:

The output of the first turbulence filter primitive.

The output of the filter chain after adding and adjusting the Displacement Map filter primitive.

Distorting the Fabric

Fabric rarely lies flat unless stretched and even then it is hard to make the threads lie straight and parallel. We can add a random wave to the fabric by adding another Turbulence and Displacement Map pair, but this time using a lower Base Frequency. Repeat the instructions above to add the two filter primitives but this time connect the top input to the Displacement Map to the previous Displacement Map. Set the Base Frequency to a value of 0.01. Set the Type to Fractal Noise. Set the Scale to ten.

Filter Dialog image.

The Filter Effect dialog after adding and adjusting the second Turbulence and Displacement Map filter primitives.

And here is the resulting image:

The final fabric image.

The output of the filter chain after distorting the fabric.

Of course, the pattern and filter can be applied to an arbitrary shape:

The pattern and filter applied to a blob.

The pattern and filter applied to a cloth patch.

Conclusion

We have constructed a basic Fabric filter but there is plenty of room for improvement. In the next part we’ll look at ways to add color to the fabric.


A section of a bag of coffee beans.

A PNG image just for Google+ which doesn’t support SVG images.