我的SVG过滤器运行速度非常慢

时间:2017-09-09 18:10:13

标签: javascript css svg svg-filters

我有以下SVG过滤器:

<svg style="visibility: hidden; height: 0; width: 0;">
    <filter id="rgbShift">
        <feOffset in="SourceGraphic" dx="1" dy="-1" result="text1" />
        <feFlood flood-color="#FF0000" result="redColor" />
        <feComposite in="redColor" in2="text1" operator="arithmetic" k1="1" result="red" />
        <feOffset in="SourceGraphic" dx="-1" dy="2" result="text2" />
        <feFlood flood-color="#00FF00" result="greenColor" />
        <feComposite in="greenColor" in2="text2" operator="arithmetic" k1="1" result="green" />
        <feOffset in="SourceGraphic" dx="-2" dy="1" result="text3" />
        <feFlood flood-color="#0000FF" result="blueColor" />
        <feComposite in="blueColor" in2="text3" operator="arithmetic" k1="1" result="blue" />
        <feComposite in="red" in2="green" operator="lighter" result="rb" />
        <feComposite in="rb" in2="blue" operator="lighter" />
    </filter>
</svg>

此滤镜适用于我正在制作的游戏中的菜单屏幕。我想对游戏本身应用相同的过滤器,但它运行得非常慢,可能是因为元素几乎不断在页面上移动。有没有办法让我的过滤器运行得更快?

2 个答案:

答案 0 :(得分:4)

虽然我没有正式的结果,但在Inkscape中的单个jpg图片上测试它给我的印象是以下过滤器明显更快,而在数学上是相同的AFAIK:

<filter id="rgbShift">
    <feOffset in="SourceGraphic" dx="1" dy="-1" />
    <feComponentTransfer result="red">
        <feFuncG type="discrete" tableValues="0" />
        <feFuncB type="discrete" tableValues="0" />
    </feComponentTransfer>
    <feOffset in="SourceGraphic" dx="-1" dy="2" />
    <feComponentTransfer result="green">
        <feFuncR type="discrete" tableValues="0" />
        <feFuncB type="discrete" tableValues="0" />
    </feComponentTransfer>
    <feOffset in="SourceGraphic" dx="-2" dy="1" />
    <feComponentTransfer result="blue">
        <feFuncR type="discrete" tableValues="0" />
        <feFuncG type="discrete" tableValues="0" />
    </feComponentTransfer>
    <feComposite in="red" in2="green" operator="arithmetic" k2="1" k3="1" result="rb" />
    <feComposite in="rb" in2="blue" operator="arithmetic" k2="1" k3="1" />
</filter>

这是否足够,我不知道。以下措施可能有助于避免时间紧迫的操作(即重新计算每帧的过滤器):

  • 不要将过滤器应用于动画元素。
  • 不要将过滤器应用于元素,以使其filter effects region(已过滤元素的边界框加上默认情况下,每个方向上的10%)与动画元素的边界框重叠。无论是高于还是低于无关紧要。

答案 1 :(得分:1)

我不知道这是否是导致性能问题的原因,但是feComposite操作很慢,你的语法有很多错误。

  • 在SVG 1.1中,feComposite没有“更轻”的操作符。这是在Filters 1.0规范中添加的,并且不支持跨浏览器。您可能想要使用feComposite operator =“arithmetic”k2 =“1”k3 =“1”我相信它是等效的。
  • 使用feBlend / multiply通常比feComposite /算术更好,它看起来要快得多。

我认为你想要的原始过滤器的更正实现如下:

<filter id="rgbShift">
    <feOffset in="SourceGraphic" dx="1" dy="-1" result="text1" />
    <feFlood flood-color="#FF0000" result="redColor" />
    <feBlend in="text1" in2="redColor" mode="multiply" result="red"/>
    <feOffset in="SourceGraphic" dx="-1" dy="2" result="text2" />
    <feFlood flood-color="#00FF00" result="greenColor" />
    <feBlend in="text2" in2="greenColor" mode="multiply" result="green"/>
    <feOffset in="SourceGraphic" dx="-2" dy="1" result="text3" />
    <feFlood flood-color="#0000FF" result="blueColor" />
    <feBlend in="text3" in2="blueColor" mode="multiply" result="blue"/>
    <feComposite in="red" in2="green" operator="arithmetic" k2="1" k3="1" result="rb" />
    <feComposite in="rb" in2="blue" operator="arithmetic" k2="1" k3="1"/>
</filter>