An SVG path element becomes unexpectedly pixelated on retina screens if I apply a filter to it. Without the filter, it looks nice and smooth.
I'm using a gaussian blur and a color matrix:
<filter id="svg-filter-rounded-corners" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" />
<feColorMatrix mode="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 -25" />
</filter>
Here's a reproducible example. The circle on the left has the filter, the circle on the right does not.
<svg xmlns="http://www.w3.org/2000/svg" width="400" height="200" viewBox="0 0 400 200">
<defs>
<filter id="filter" x="-50%" y="-50%" width="200%" height="200%">
<feGaussianBlur stdDeviation="3" />
<feColorMatrix mode="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 50 -25" />
</filter>
</defs>
<circle filter="url(#filter)" cx="100" cy="100" r="90" fill="none" stroke="#221C35" stroke-width="10" />
<circle cx="300" cy="100" r="90" fill="none" stroke="#221C35" stroke-width="10" />
</svg>
This is occurring in both Chrome and Firefox, on MacOS.
Is there anything I can do to keep the path smooth even with the filters applied?
This is crispy even on Chrome/Windows. And the issue is that the values you're using for your feColorMatrix are too large. It's nuking the anti-aliasing completely. Try:
<feColorMatrix mode="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 8 -4" />
Which gives a more reasonable result. If you don't like that result, you could try a more detailed manipulation of opacity using feComponentTransfer instead of the feColorMatrix.
<feComponentTransfer>
<feFuncA type="table" tableValues = "0 0 0 0 0.5 1 1 1 1 1 1 1 1 1 1 1"/>
</feComponentTransfer>