前置知识: SVG

SVG 滤镜详解

6 minAdvanced2026/7/18

filter、feGaussianBlur、feDropShadow、feColorMatrix、滤镜组合与光照。

1. filter 基础

<filter><defs> 中定义,通过 filter="url(#id)" 应用到元素。

<svg viewBox="0 0 200 100">
  <defs>
    <filter id="blur" x="-20%" y="-20%" width="140%" height="140%">
      <feGaussianBlur stdDeviation="3" />
    </filter>
  </defs>
  <rect x="20" y="20" width="160" height="60" fill="#4f5bd5" filter="url(#blur)" />
</svg>

1.1 filter 区域属性

属性说明默认值
x, y滤镜区域左上角-10%
width, height滤镜区域尺寸120%
filterUnits区域坐标系objectBoundingBox
primitiveUnits滤镜基元坐标userSpaceOnUse

模糊、阴影等效果会超出元素边界,需扩大 filter 区域否则被裁剪。

2. feGaussianBlur 高斯模糊

<filter id="blur5">
  <feGaussianBlur stdDeviation="5" />
</filter>
<filter id="blur-xy">
  <feGaussianBlur stdDeviation="5 2" />
  <!-- X 方向模糊 5,Y 方向模糊 2 -->
</filter>
参数说明
stdDeviation模糊半径,可分别指定 X Y

3. feDropShadow 阴影

<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
  <feDropShadow dx="4" dy="4" stdDeviation="3" flood-color="#000" flood-opacity="0.3" />
</filter>
参数说明默认值
dx, dy阴影偏移2
stdDeviation模糊半径2
flood-color阴影颜色#000
flood-opacity阴影透明度1

3.1 内阴影模拟

SVG 无原生 inner-shadow,可通过 feComposite 实现:

<filter id="inner-shadow">
  <feOffset dx="0" dy="2">
    <feDropShadow dx="0" dy="2" stdDeviation="2" flood-color="#000" flood-opacity="0.5" />
  </feOffset>
  <feComposite operator="out" in="SourceGraphic" />
  <feComposite operator="in" in2="SourceAlpha" />
  <feComposite operator="over" in="SourceGraphic" />
</filter>

4. feColorMatrix 颜色矩阵

<feColorMatrix> 通过 4×5 矩阵变换 RGBA 通道,实现调色、灰度、反相等效果。

4.1 矩阵语法

<filter id="grayscale">
  <feColorMatrix
    type="matrix"
    values="0.3 0.59 0.11 0 0
            0.3 0.59 0.11 0 0
            0.3 0.59 0.11 0 0
            0   0    0    1 0"
  />
</filter>

每个像素的 RGBA 按矩阵相乘:R' = 0.3R + 0.59G + 0.11B + 0A + 0,得到灰度。

4.2 预设型 type

说明
matrix自定义矩阵
saturate饱和度(0=灰度,1=原色,2=高饱和)
hueRotate色相旋转(度)
luminanceToAlpha亮度转透明度
<filter id="saturate">
  <feColorMatrix type="saturate" values="2" />
</filter>

<filter id="hue-rotate">
  <feColorMatrix type="hueRotate" values="90" />
</filter>

5. feComponentTransfer 通道映射

对每个颜色通道独立应用函数(亮度、对比度)。

<filter id="brightness">
  <feComponentTransfer>
    <feFuncR type="linear" slope="1.5" intercept="0" />
    <feFuncG type="linear" slope="1.5" intercept="0" />
    <feFuncB type="linear" slope="1.5" intercept="0" />
  </feComponentTransfer>
</filter>
函数说明
feFuncR/G/B/A通道函数
type="linear"线性:y = slope*x + intercept
type="table"表格查找
type="discrete"阶梯量化
type="gamma"伽马校正

6. feMerge 合成

<feMerge> 将多个滤镜结果叠加合成。

<filter id="glow">
  <feGaussianBlur stdDeviation="4" result="blur" />
  <feMerge>
    <feMergeNode in="blur" />
    <feMergeNode in="blur" />
    <feMergeNode in="SourceGraphic" />
  </feMerge>
</filter>

原理:模糊结果叠加两次产生更强光晕,最后叠加原,形成发光效果。

7. 滤镜基元 result/in

每个滤镜基元可用 result 命名输出,后续基元用 in 引用

<filter id="emboss">
  <feGaussianBlur in="SourceAlpha" stdDeviation="1" result="blur" />
  <feSpecularLighting
    in="blur"
    surfaceScale="3"
    specularConstant="1"
    specularExponent="20"
    lighting-color="#fff"
    result="spec"
  >
    <fePointLight x="-50" y="-50" z="200" />
  </feSpecularLighting>
  <feComposite in="spec" in2="SourceAlpha" operator="in" result="specMasked" />
  <feComposite
    in="SourceGraphic"
    in2="specMasked"
    operator="arithmetic"
    k1="0"
    k2="1"
    k3="1"
    k4="0"
  />
</filter>
输入含义
SourceGraphic原始彩色
SourceAlpha原始形的 alpha 通道(黑白蒙版)
BackgroundImage背景(需 enable-background
Previous前一基元结果
自定义 result命名的中间结果

8. feOffset 偏移

<filter id="offset">
  <feOffset dx="10" dy="10" in="SourceAlpha" />
  <feFlood flood-color="#000" flood-opacity="0.3" />
  <feComposite operator="in" in2="SourceAlpha" />
  <feMerge>
    <feMergeNode />
    <feMergeNode in="SourceGraphic" />
  </feMerge>
</filter>

等价于 feDropShadow 的手动实现。

9. feFlood 纯色填充

<filter id="red-overlay">
  <feFlood flood-color="#d63031" flood-opacity="0.5" />
  <feComposite operator="in" in2="SourceGraphic" />
</filter>

形填充为指定颜色,配合 feComposite 可制作色彩滤镜。

10. feSpecularLighting 光照

<filter id="metallic">
  <feGaussianBlur in="SourceAlpha" stdDeviation="2" result="blur" />
  <feSpecularLighting
    in="blur"
    surfaceScale="5"
    specularConstant="1"
    specularExponent="20"
    lighting-color="#fff"
    result="spec"
  >
    <feDistantLight azimuth="135" elevation="45" />
  </feSpecularLighting>
  <feComposite in="spec" in2="SourceAlpha" operator="in" />
  <feComposite in="SourceGraphic" operator="arithmetic" k1="0" k2="1" k3="1" k4="0" />
</filter>
光源说明
<feDistantLight>平行光,参数 azimuth/elevation
<fePointLight>点光源,参数 x/y/z
<feSpotLight>聚光灯

11. feTurbulence 噪声

生成柏林噪声,常用于纹理、烟雾、水波。

<filter id="texture">
  <feTurbulence type="fractalNoise" baseFrequency="0.5" numOctaves="3" />
  <feColorMatrix type="matrix" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.2 0" />
  <feComposite operator="in" in2="SourceGraphic" />
</filter>
参数说明
typefractalNoise / turbulence
baseFrequency频率(越大颗粒越细)
numOctaves倍频数(细节层次)
seed随机种子
stitchTiles平铺缝合

12. feDisplacementMap 位移映射

根据另一张的像素值扭曲当前

<filter id="ripple">
  <feTurbulence type="turbulence" baseFrequency="0.02" numOctaves="2" result="noise" />
  <feDisplacementMap
    in="SourceGraphic"
    in2="noise"
    scale="20"
    xChannelSelector="R"
    yChannelSelector="G"
  />
</filter>

scale=20 表示根据噪声 R/G 通道值最大位移 20 像素。

13. 滤镜组合实战

13.1 霓虹发光

<filter id="neon" x="-50%" y="-50%" width="200%" height="200%">
  <feGaussianBlur stdDeviation="4" result="blur1" />
  <feGaussianBlur in="SourceGraphic" stdDeviation="8" result="blur2" />
  <feColorMatrix
    in="blur1"
    type="matrix"
    values="0 0 0 0 0.3
                         0 0 0 0 0.4
                         0 0 0 0 1
                         0 0 0 1.5 0"
    result="glow1"
  />
  <feColorMatrix
    in="blur2"
    type="matrix"
    values="0 0 0 0 0.3
                         0 0 0 0 0.4
                         0 0 0 0 1
                         0 0 0 0.8 0"
    result="glow2"
  />
  <feMerge>
    <feMergeNode in="glow2" />
    <feMergeNode in="glow1" />
    <feMergeNode in="SourceGraphic" />
  </feMerge>
</filter>

13.2 玻璃磨砂

<filter id="frosted-glass">
  <feGaussianBlur stdDeviation="5" />
  <feColorMatrix type="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 0.8 0.1" />
</filter>

14. 性能与兼容

14.1 性能注意

问题解决方案
滤镜区域过大缩小 filter 的 width/height 到刚好覆盖效果范围
嵌套滤镜避免在 filter 内再调用 filter
大量元素应用滤镜优先考虑预渲染为位
复杂 feTurbulencenumOctaves ≤ 3

14.2 浏览器兼容

  • 现代浏览器全面支持 SVG 滤镜
  • feDropShadow 在 IE 不支持,需用 feOffset + feFlood + feComposite 替代
  • 滤镜在 <img> 引用的 SVG 中可能不生效,需内联或 <object>

15. 实战:玻璃质感卡片

<svg viewBox="0 0 400 200">
  <defs>
    <linearGradient id="bg" x1="0%" x2="100%" y2="100%">
      <stop offset="0%" stop-color="#4f5bd5" />
      <stop offset="100%" stop-color="#00b894" />
    </linearGradient>
    <filter id="card-shadow">
      <feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.2" />
    </filter>
    <filter id="card-glow">
      <feGaussianBlur stdDeviation="2" result="b" />
      <feMerge>
        <feMergeNode in="b" />
        <feMergeNode in="SourceGraphic" />
      </feMerge>
    </filter>
  </defs>
  <!-- 背景 -->
  <rect width="400" height="200" fill="url(#bg)" />
  <!-- 玻璃卡片 -->
  <rect
    x="60"
    y="40"
    width="280"
    height="120"
    rx="16"
    fill="#fff"
    fill-opacity="0.15"
    filter="url(#card-shadow)"
  />
  <text
    x="200"
    y="100"
    text-anchor="middle"
    font-size="24"
    fill="#fff"
    font-weight="bold"
    filter="url(#card-glow)"
  >
    Glass Card
  </text>
</svg>

下一篇介绍裁剪与蒙版。