Reputation: 103
I have the following SVG filter:
<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>
This filter is applied to my menu screen in a game I am working on. I want to apply the same filter to the game itself, but it runs very slowly, probably because elements are almost constantly moving on the page. Is there a way to make my filter run faster?
Upvotes: 0
Views: 1359
Reputation: 31715
I do not know if it's the cause of your performance problems, but feComposite is a slow operation and you have many mistakes in your syntax.
A corrected implementation of what I think you wanted with your original filter would be as follows:
<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>
Upvotes: 1
Reputation: 21821
While I have no formal results, testing it on a single jpg picture in Inkscape gives me the impression that the following filter is perceptably faster, while being mathematically identical 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>
Whether that is enough, I don't know. The following measures might help avoiding time-critical operations (i. e. recomputing the filter for every frame):
Upvotes: 4