Masking SVG-filter,不是简单的结合mask和filter

Masking SVG-filter, not simply combining mask and filter

我正在尝试将 fractalNoise 过滤器应用于 HTML 元素。但是,我不希望整个元素受到影响,而是让过滤器从下到上逐渐增加。 为了实现这一点,我尝试先创建噪声滤波器,然后将其与遮罩滤波器配对。

我 运行 遇到两个问题:第一个但可能较小的问题是过滤后的元素出现在未过滤的元素之上。

第二个问题是我的想法似乎根本行不通:遮罩滤镜只是让元素淡出。 我想原因是我没有将遮罩应用于噪声滤波器,而只是将噪声和遮罩滤波器应用于元素。不幸的是,这是我在网上找到的唯一教程,因为此过程适用于蒙版模糊滤镜。

这是我的过滤器的样子:

<filter id="noiselayer" width="200%" height="200%">

    <feTurbulence type="fractalNoise" baseFrequency="0.0001 0.2" numOctaves="1" result="warp"></feTurbulence>
    <feDisplacementMap xChannelSelector="R" yChannelSelector="G" scale="30" in="SourceGraphic" in2="warp" result="noise"/>

    <feImage id="feimage" xlink:href="data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iRWJlbmVfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAxOTIwIDEwODAiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDE5MjAgMTA4MDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6dXJsKCNTVkdJRF8xXyk7fQ0KPC9zdHlsZT4NCjxnIGlkPSJWZXJsYXVmIj4NCgk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzFfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijk2MCIgeTE9IjEwODAiIHgyPSI5NjAiIHkyPSItMi43Mjg0ODRlLTEyIj4NCgkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6I0ZGRkZGRjtzdG9wLW9wYWNpdHk6MCIvPg0KCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMDAwMDAwIi8+DQoJPC9saW5lYXJHcmFkaWVudD4NCgk8cmVjdCB4PSIwIiB5PSIwIiBjbGFzcz0ic3QwIiB3aWR0aD0iMTkyMCIgaGVpZ2h0PSIxMDgwIi8+DQo8L2c+DQo8L3N2Zz4=" width= "100%" result="mask" />

    <feComposite in2="mask" in="noise"  operator="in" result="comp" />

    <feMerge result="merge">
        <feMergeNode in="SourceGraphic" />
        <feMergeNode in="comp" />
    </feMerge> 

这是一个悲伤的 JSFiddle 来说明这个问题: https://jsfiddle.net/ew09thnx/11/

非常感谢任何解决方法的提示!

这里要理解的关键是 feComposite 运算符="in" 使用不透明度而不是亮度来执行其遮罩功能,因此您需要将该渐变从 black/white 渐变转换为全具有可变不透明度渐变的黑色。您可以使用 feColorMatrix/luminanceToAlpha.

如果您只想创建一些噪音并将其叠加在另一个元素上,那么这是一种更好的方法。 (将您的 baseFrequency 值更改为更明显的值)。

(我以前从未见过在 head 元素中定义的过滤器 - 我希望它可以跨浏览器工作 - 我不明白你为什么将它应用于 HTML 元素而不是body 元素。)

<filter id="noiselayer" width="200%" height="200%">

      <feTurbulence result="fNoise" type="fractalNoise" numOctaves="6" baseFrequency="1.98"/> 
      <feColorMatrix in="fNoise" type="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 7 -3" result="noise"/>

      <feImage id="feimage" xlink:href="data:image/svg+xml;charset=utf-8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAyMy4wLjEsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjxzdmcgdmVyc2lvbj0iMS4xIiBpZD0iRWJlbmVfMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiDQoJIHZpZXdCb3g9IjAgMCAxOTIwIDEwODAiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDE5MjAgMTA4MDsiIHhtbDpzcGFjZT0icHJlc2VydmUiPg0KPHN0eWxlIHR5cGU9InRleHQvY3NzIj4NCgkuc3Qwe2ZpbGw6dXJsKCNTVkdJRF8xXyk7fQ0KPC9zdHlsZT4NCjxnIGlkPSJWZXJsYXVmIj4NCgk8bGluZWFyR3JhZGllbnQgaWQ9IlNWR0lEXzFfIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijk2MCIgeTE9IjEwODAiIHgyPSI5NjAiIHkyPSItMi43Mjg0ODRlLTEyIj4NCgkJPHN0b3AgIG9mZnNldD0iMCIgc3R5bGU9InN0b3AtY29sb3I6I0ZGRkZGRiIvPg0KCQk8c3RvcCAgb2Zmc2V0PSIxIiBzdHlsZT0ic3RvcC1jb2xvcjojMDAwMDAwIi8+DQoJPC9saW5lYXJHcmFkaWVudD4NCgk8cmVjdCB4PSIwIiB5PSIwIiBjbGFzcz0ic3QwIiB3aWR0aD0iMTkyMCIgaGVpZ2h0PSIxMDgwIi8+DQo8L2c+DQo8L3N2Zz4=" width= "100%"  />
      <feColorMatrix type="luminanceToAlpha" result="mask"/>

      <feComposite in2="mask" in="noise"  operator="in" result="comp" />

      <feMerge result="merge">
        <feMergeNode in="SourceGraphic" />
        <feMergeNode in="comp" />
      </feMerge> 

    </filter>