feDisplacementMap is one of the SVG filters that always seems daunting for me to understand. But once I looked into it, it is not so complicated and is actually fun to play with.
Let's first see what this SVG filter can do.
feDisplacementMap
takes in two input source in
and in2
. in
is the image to be displaced, and in2
is used to calculated how in
will be displaced. In this case, we used a forest image for in
and an image created with feTurbulence. We can therefore create a ripple-like effect on the forest image.
In essence, what feDisplacementMap
is doing is looping through each pixel on an image and move the pixel around based on a transformation formula.
Transformation Formula
P'(x,y) ← P( x + scale * (XC(x,y) - 0.5), y + scale * (YC(x,y) - 0.5))
Here's a breakdown of the formula:
-
P'(x, y)
on the left is the coordinates after transformation - The right part is how it is transformed
-
XC(x,y)
andYC(x,y)
means the RGB value of the given coordinates on thein2
image divided by 255, so it will be between 0 and 1 - The larger the
scale
is, the more a pixel is displaced
Example
<filter>
<!-- ... -->
<feDisplacementMap in2="turbulence" in="SourceGraphic" scale="50"
xChannelSelector="R" yChannelSelector="G"/>
</filter>
If we compare the syntax of feDisplacementMap
and the transformation formula, we realize that:
- scale corresponds to
scale
- xChannelSelector specifies which color channel to look at for
XC(x,y)
- yChannelSelector specifies which color channel to look at for
YC(x,y)
Note: SourceGraphic is the original input to the SVG filter, which is the forest image.
Here's the full example:
<svg>
<defs>
<filter id="displace">
<feTurbulence id="turbulence" baseFrequency="0.1 0.1" result="turbulence" />
<feDisplacementMap in2="turbulence" in="SourceGraphic" scale="10" xChannelSelector="A" yChannelSelector="A"/>
</filter>
</defs>
<image href="https://images.unsplash.com/photo-1441974231531-c6227db76b6e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1171&q=80" height="100%" width="100%" filter="url(#displace)"/>
</svg>
Now that we understand feDisplacementMap
We can go creative to experiment with interesting graphics with feDisplacementMap
!
Top comments (1)
What value do I use to only displace the X using Green for example and not Y at all? because yChannelSelector cannot be undefined so..
For example I attempted to set X to R, which goes from 128 to 255, so 0.5 -> 1 ? But then set Y to G which I've left at 128, so this should equate to 0.5 correct? But it still seems to displace the Y pixels by a bit..