1概述

feDisplacementMap 是 SVG 滤镜中最强大的滤镜之一。也是最具破坏性的滤镜之一。

他和 PS 中的置换滤镜的原理是一样的,都是通过一个图像的颜色值来改变另一个图像的像素位置。

他可以利用一张图(通常是纹路或者噪声)的颜色信息,来推挤另外一张图的像素,从而产生扭曲、液化、变形、故障、手绘等风格。

他的参数如下:

  • in: 要被变形的原始图像。
  • in2: 置换图(Displacement Map),通常是噪点或特定的梯度图。
  • scale: 变形的强度。值越大,拉伸/扭曲越严重。
  • xChannelSelector / yChannelSelector: 指定用置换图的哪个颜色通道(R, G, B, A)来控制 X 轴或 Y 轴的偏移。通常设置:R 控制 X,G 控制 Y

滤镜会遍历 in 的每一个像素,查看 in2 对应位置的颜色值

  • 如果颜色值 > 50% (中性灰),像素向正方向移动。
  • 如果颜色值 < 50%,像素向负方向移动。
  • 如果颜色值 = 50%,像素不动。

feTurbulence 可以在不基于任何图像的情况下,生成噪点纹理。从云彩、大理石、水波,到如今设计圈大火的“噪点渐变”和“磨砂质感”,核心全是它。本文中的案例,也会大量借助他来实现。

他的关键参数如下

baseFrequency: 控制噪点的频率。值越大,噪点越密集。

  • 数值越小,波纹越大,越趋于云彩或者地势
  • 数值越大,颗粒越细,越趋于沙砾或者磨砂质感
  • 支持 x 和 y 两个方向的频率控制,可以控制不同的方向噪点,来制作拉丝效果、异常像素等效果

numOctaves: 控制噪点的层数,即细节丰富度

  • 数值为 1 时,表现为模糊、平滑
  • 数值为 5 时,边缘锋利,计算量大
  • 通常 2~3 层即可满足大多数需求

type: 类型,有两种:

  • turbulence: 湍流噪点,产生随机、不规则的噪点,适合火焰、爆炸等效果
  • fractalNoise: 分形噪点,产生更自然的条纹,适合云雾、柔和过渡的场景

2基础:水波纹 (Ripple)

最常见的用法是结合 feTurbulence 生成的噪点来实现水波纹效果。 我们让噪点在 baseFrequency 上进行动画,从而带动置换效果的流动。

预览
index.tsx
1
<filter id="demo1-ripple">
2
{/* 1. 生成大尺度的湍流噪点,模拟水波 */}
3
<feTurbulence
4
type="turbulence"
5
baseFrequency="0.01 0.015" // X方向高频 (0.01) => 密集的噪点,Y方向低频 (0.015) => 拉伸的长条
6
numOctaves="2"
7
result="noise"
8
>
9
{/* 让噪点动起来 */}
10
<animate attributeName="baseFrequency" values="0.01 0.015;0.01 0.025;0.01 0.015" dur="10s" repeatCount="indefinite" />
11
</feTurbulence>
12
13
{/* 2. 使用噪点置换原图 */}
14
<feDisplacementMap
15
in="SourceGraphic"
16
in2="noise"
17
scale="20"
18
xChannelSelector="R" // 使用红色通道控制X偏移
19
yChannelSelector="G" // 使用绿色通道控制Y偏移
20
/>
21
</filter>

3故障艺术 (Glitch)

通过控制噪点的频率(X 轴高频,Y 轴低频),我们可以制造出水平方向的撕裂效果,非常适合赛博朋克风格的故障文字。

预览
index.tsx
1
<filter id="demo2-glitch">
2
<feTurbulence
3
type="fractalNoise" // 使用分形噪点,产生更自然的条纹
4
baseFrequency="0.5 0.005" // X方向高频 (0.5) => 密集的噪点,Y方向低频 (0.005) => 拉伸的长条
5
numOctaves="2" // 噪点层数,层数越多,条纹越明显
6
result="noise"
7
/>
8
9
<feDisplacementMap
10
in="SourceGraphic"
11
in2="noise"
12
scale="20"
13
xChannelSelector="R"
14
yChannelSelector="G"
15
/>
16
</filter>

4磨砂玻璃 (Frosted Glass)

利用高频噪点进行细微的像素置换,可以模拟磨砂玻璃的粗糙表面。这实际上是一种高级的模糊,比 feGaussianBlur 更有质感。

预览
index.tsx
1
<filter id="demo3-frost">
2
<feTurbulence
3
type="fractalNoise" // 使用分形噪点,产生更自然的条纹
4
baseFrequency={baseFrequency} // 高频噪点,产生细小的颗粒感
5
numOctaves="3" // 噪点层数,层数越多,颗粒感越强
6
stitchTiles="stitch"
7
result="noise"
8
/>
9
<feDisplacementMap
10
in="SourceGraphic"
11
in2="noise"
12
scale="10"
13
xChannelSelector="R"
14
yChannelSelector="G"
15
/>
16
</filter>

5手绘风格 (Squiggle)

给规则的几何图形或文字添加低频噪点的置换,可以让线条变得不规则,模仿手绘的颤抖线条效果。

预览
index.tsx
1
<filter id="demo4-sketch">
2
<feTurbulence
3
type="fractalNoise" // 使用分形噪点,产生更自然的条纹
4
baseFrequency="0.04" // 低频噪点,产生规则的条纹
5
numOctaves="3" // 噪点层数,层数越多,条纹越明显
6
result="noise"
7
/>
8
<feDisplacementMap
9
in="SourceGraphic"
10
in2="noise"
11
scale="5"
12
xChannelSelector="R"
13
yChannelSelector="G"
14
/>
15
</filter>

6交互式全息卡片

结合 React 的状态管理,我们可以动态改变 scale 属性。 鼠标悬停时瞬间增大 scale,可以制作出“受到干扰”或“全息投影不稳定”的酷炫交互效果。

预览
index.tsx
1
'use client'
2
import { useState } from 'react'
3
4
export default function App() {
5
const [scale, setScale] = useState(0)
6
7
return (
8
<div
9
className="w-full h-full flex flex-col items-center justify-center bg-gray-900 rounded-xl p-8 relative overflow-hidden"
10
onMouseEnter={() => setScale(30)}
11
onMouseLeave={() => setScale(0)}
12
>
13
<svg className='w-full max-w-[400px] cursor-pointer' viewBox="0 0 400 250">
14
<defs>
15
<filter id="demo5-interact">
16
<feTurbulence
17
type="fractalNoise" // 使用分形噪点,产生更自然的条纹
18
baseFrequency="0.1 0.01" // X方向高频 (0.1) => 密集的噪点,Y方向低频 (0.01) => 拉伸的长条
19
numOctaves="2" // 噪点层数,层数越多,条纹越明显
20
result="noise"
21
>
22
<animate attributeName="baseFrequency" values="0.1 0.01; 0.1 0.04; 0.1 0.01" dur="0.2s" repeatCount="indefinite" />
23
</feTurbulence>
24
25
<feDisplacementMap
26
in="SourceGraphic"
27
in2="noise"
28
scale={scale} // 变形的强度。值越大,拉伸/扭曲越严重。
29
xChannelSelector="R" // 使用红色通道控制X偏移
30
yChannelSelector="G" // 使用绿色通道控制Y偏移
31
className="transition-all duration-300"
32
/>
33
</filter>
34
</defs>
35
36
<g filter="url(#demo5-interact)">
37
<rect x="20" y="20" width="360" height="210" rx="15" fill="#6366f1" />
38
<text x="50" y="80" fontFamily="sans-serif" fontSize="24" fill="white" fontWeight="bold">HOVER CARD</text>
39
</g>
40
</svg>
41
</div>
42
)
43
}

7液化效果 (Liquid)

通过控制噪点的频率(X 轴高频,Y 轴低频),我们可以制造出水平方向的撕裂效果,非常适合赛博朋克风格的故障文字。

预览
index.tsx
1
<filter id="melt-filter">
2
{/* 定义两个维度的噪声,Y轴频率稍低,模拟重力下垂感 */}
3
<feTurbulence type="turbulence" baseFrequency="0.02 0.08" numOctaves="3" seed="5" result="noise">
4
{/* SVG 动画让流体动起来 */}
5
<animate attributeName="baseFrequency" dur="10s" values="0.02 0.08;0.02 0.1;0.02 0.08" repeatCount="indefinite"/>
6
</feTurbulence>
7
{/* 使用噪点置换原图 */}
8
<feDisplacementMap in="SourceGraphic" in2="noise" scale="30" xChannelSelector="R" yChannelSelector="G" />
9
</filter>

7总结

feDisplacementMap 的核心在于 in2 (置换图) 的设计:

  • 噪点 (Turbulence):自然、随机的效果(水、云、故障)。
  • 梯度 (Gradient):规律的变形(透镜、放大镜、枕形畸变)。
  • 几何图形:硬边缘的错位。
预览
index.tsx
1
<filter id="ripple-filter">
2
{/* 低频噪声,模拟缓和的水波 */}
3
<feTurbulence type="turbulence" baseFrequency="0.02 0.02" numOctaves="2" seed="2" result="ripple">
4
<animate attributeName="baseFrequency" dur="5s" values="0.01 0.01;0.02 0.04;0.01 0.01" repeatCount="indefinite" />
5
</feTurbulence>
6
{/* 稍微增加一点 scale */}
7
<feDisplacementMap in="SourceGraphic" in2="ripple" scale="20" xChannelSelector="R" yChannelSelector="G" />
8
</filter>
专栏首页
到顶
专栏目录