【问题标题】:My SVG Filter is running extremely slowly我的 SVG 过滤器运行非常缓慢
【发布时间】:2017-09-13 13:57:15
【问题描述】:

我有以下 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>

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

【问题讨论】:

    标签: javascript css svg svg-filters


    【解决方案1】:

    虽然我没有正式的结果,但在 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%)与动画元素的边界框重叠。它们是在上面还是在下面都没有关系。

    【讨论】:

    • 已编辑以符合 SVG 1.1 feComposite 模式
    • 只是一个简短的说明 - Edge 中存在一个错误(我认为在 Firefox 中也是如此),您必须为 type="discrete" 指定 tableValues="0 0"
    【解决方案2】:

    我不知道这是否是您的性能问题的原因,但是 feComposite 是一个缓慢的操作,并且您的语法有很多错误。

    • 在 SVG 1.1 中,feComposite 没有“更轻”的运算符。这是在过滤器 1.0 规范中添加的,尚不支持跨浏览器。您可能想使用 feComposite operator="arithmetic" k2="1" k3="1" 我认为这是等效的。
    • 通常使用 feBlend/multiply 比使用 feComposite/arithmetic 更好,它似乎要快得多。

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

    <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>
    

    【讨论】:

    • Inkscape 为 feComposite 提供了 lighter 运算符。它遵循 CSS feComposite 和 Porter Duff plus 定义,所以 k1 = k4 = 0k2 = k3 = 1
    • 刚刚看到lighter也在Firefox中实现了
    • 你是对的。我不知道在 Filters 1.0 规范中添加了打火机。我对规范的阅读是 operator="lighter" 是 operator="arithmetic" k2="1" k3="1" 的简写,如果你正在做“lighter”,你不应该指定 k “?我可能是错的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多