SVG feDisplacementMap 怎样选择位移使用的颜色通道
来源:17golang原创
时间:2026-10-31 03:10:20 104浏览 收藏
我第一次把 SVG 的波纹贴图接到 上时,最容易改错的不是 scale,而是颜色通道:明明换了一张位移图,画面却只沿一个方向抖动,或者透明区域突然把文字拉成一条线。实际选择规则很直接:xChannelSelector 决定水平方向读取哪个通道,yChannelSelector 决定垂直方向读取哪个通道;通道可以是 R、G、B 或 A,默认值是 A。
- 先问位移图把数据放在哪个通道,再填写选择器;不要按“红色更适合横向”这类固定经验硬套。
- 同一张灰度图可以让 x、y 都读取同一个通道;RGB 彩色位移图则可以把两组数据拆到不同通道。
scale控制位移幅度,通道值 0.5 是中性点,低于和高于 0.5 的值分别产生相反方向的偏移。
先把颜色通道当成位移数据源
feDisplacementMap 使用 in2 的像素值来移动 in 的像素。选择器的职责不是给画面“上色”,而是告诉滤镜:每个输出像素的水平坐标和垂直坐标分别从哪一个通道取数。
我现在会先在纸上写一行数据约定:R 存水平位移、G 存垂直位移,或者两个方向都从灰度通道读取。约定确定以后,属性就不会跟着视觉效果反复试错。

R、G、B、A 应该怎样选
四个通道在语义上没有“谁更高级”的排序,真正的选择取决于 in2 的数据布局。下表是我在设计位移贴图时使用的速查表:
| 通道 | 它表示什么 | 适合的情况 | 容易踩的坑 |
|---|---|---|---|
R | 红色分量 | 把一组独立的水平或垂直数据放进 RGB 贴图 | 误以为画面越红,位移一定越大;实际还要看数值和 scale |
G | 绿色分量 | 与 R 配对存放第二组方向数据 | 图像软件的颜色预览可能掩盖了通道真实数值 |
B | 蓝色分量 | 需要第三组数据,或已有蓝色通道位移图 | 蓝色视觉较明显不等于通道数值更适合 |
A | 透明度分量 | 用透明度作为遮罩或已有带 alpha 的灰度位移图 | 默认值就是 A,透明区域可能被误当成零位移 |
如果位移图是普通灰度图,通常最省心的写法是让 xChannelSelector 和 yChannelSelector 都指向实际存放灰度值的通道,并显式写出来。这样即使后来替换了素材,也不必猜浏览器默认取的是哪一层。
灰度图不要把默认 A 当成约定
很多 PNG 的可见灰度内容都在 RGB 里,但它可能没有有意义的 alpha。此时若省略选择器,默认的 A 通道可能整张都是 1,结果就是位移图看起来有纹理,滤镜却没有按纹理改变方向。
下面的示例把红色通道用于横向、绿色通道用于纵向。两通道都以 0.5 附近作为中性值,便于把一张彩色位移图拆成两个方向:
这里的 feTurbulence 只是生成示例用的 in2,不是位移算法本身。换成真实图片时,仍然要确认图片是否真的把两组方向数据放进了 R、G;如果只是一张透明度遮罩,应改成 A/A 或把灰度数据转换到明确的通道。
scale 决定位移幅度,0.5 是中性点
scale 不是“强度开关”,而是把通道值相对于 0.5 的偏离放大。通道值接近 0.5 时,位移接近零;低于 0.5 与高于 0.5 会产生相反方向。把 scale 调大只会放大已有方向,不会改变你选择的通道。

因此我通常按这个顺序调参:
- 先把
scale设为较小的正数,确认画面确实在变化。 - 固定
scale,单独替换xChannelSelector,观察水平变化是否来自预期通道。 - 再替换
yChannelSelector,确认垂直变化没有被同一通道或 alpha 覆盖。 - 最后才扩大
scale,并给滤镜留出足够的边界区域,避免内容被裁掉。
同一通道和两个通道,分别适合什么场景
只做柔和的水波、玻璃或噪声扰动时,同一张灰度图同时给 x、y 使用很实用,素材简单,调试成本低。想做有明确方向的风吹、斜切或地形起伏时,R/G 分开存两组值会更好控制。A 通道则适合“透明度就是位移权重”的素材,但必须确认 alpha 是有意设计的,而不是导出图片时顺手留下的透明层。
一个小经验是:如果切换通道后画面完全不动,不要立刻把 scale 调到很大。先检查通道是否接近常量、是否被预乘 alpha 影响,以及素材的可见纹理是否真的对应了该通道的数值。
用最小检查清单确认选择没有错
- 检查输入:
in2是否确实指向位移图或上一个滤镜结果。 - 检查选择器:明确写出
xChannelSelector和yChannelSelector,不要依赖默认 A。 - 检查数据:选中的通道是否有变化,是否把整张图导出成了常量或全透明。
- 检查幅度:先用小
scale,再逐步增加,避免把裁剪问题误认为通道错误。 - 检查方向:交换 R/G 或交换 x/y 选择器,若变化方向随之交换,说明映射关系生效。
const displacement = document.querySelector('#ripple');
// 只改变通道选择器,保留 scale,便于隔离方向问题。
function swapChannels() {
const x = displacement.querySelector('feDisplacementMap');
const oldX = x.getAttribute('xChannelSelector') || 'A';
const oldY = x.getAttribute('yChannelSelector') || 'A';
x.setAttribute('xChannelSelector', oldY);
x.setAttribute('yChannelSelector', oldX);
}
// 调试完成后仍保留显式属性,避免素材或默认值变化带来回归。
swapChannels();
最后的选择原则
选择颜色通道时,先看位移图的数据契约,再看视觉效果:水平数据放在哪里,垂直数据放在哪里,就分别把 x、y 选择器指向哪里。灰度图可以复用同一通道,彩色图可以拆分 R/G/B,alpha 图则使用 A。把选择器写明、把 0.5 当成中性点、把 scale 留到最后调,通常比盲目换颜色更快定位问题。
常见问题
省略 xChannelSelector 和 yChannelSelector 会默认读取什么?
默认值是 A。如果你的位移图没有有意义的 alpha,最好显式指定实际存放位移数据的通道。
能让 x 和 y 都使用 R 通道吗?
可以。对于单通道灰度位移图,这是常见写法;它表示两个方向共享同一份位移数据,而不是 R 天生代表水平方向。
为什么把 scale 调大后画面只是被裁掉?
位移幅度变大后,内容可能超出滤镜区域。先确认通道和方向,再扩大滤镜的 x、y、width、height,不要用更大的 scale 掩盖边界设置问题。
-
502 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
495 收藏
-
277 收藏
-
401 收藏
-
180 收藏
-
368 收藏
-
169 收藏
-
470 收藏
-
341 收藏
-
335 收藏
-
300 收藏
-
233 收藏
-
496 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习