CSS / SVG filters for fun and profit

Nowadays the web technologies support nice and fancy things, such as CSS filters. The basic filters are pretty nice for many interactions, like hover effects etc. However there is also support for SVG effects, which can be really complex and produce some really nice results. I wanted to share some little hacks with which I had fun. Unfortunately the browser support is not quite there yet, in my experience these work best in Firefox, but YMMV.

First up, a very simple "bloom" filter

bloom

<svg
   xmlns="http://www.w3.org/2000/svg"
   width="0"
   height="0">
    <filter
       id="bloom">
      <feGaussianBlur
         in="SourceGraphic"
         stdDeviation="5" />
      <feComposite
         in2="SourceGraphic"
         operator="arithmetic" k2="0.8" k3="1" />
    </filter>
</svg>

This is very simple, just blur the image and add it up with the original, this makes lighter areas "leak" and makes them look bright.

Next up, slight variation of the previous, unsharp mask:

unsharp

<svg
   xmlns="http://www.w3.org/2000/svg"
   width="0"
   height="0">
    <filter
       id="unsharp">
      <feGaussianBlur
         in="SourceGraphic"
         stdDeviation="5" />
      <feComposite
         in2="SourceGraphic"
         operator="arithmetic" k2="-0.3" k3="1.3" />
    </filter>
</svg>

Here, instead of adding the blurred version, we substract it from the original, giving areas with higher contrast some depth.

Next up an homage to simpler times:

8-bit

<!-- Pixelize the image using a 2x2 pixel image and displacement map -->
<feImage width="2" height="2" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAEklEQVQI12P4/5/hPwMDA4QAACfmA/2h2gQ5AAAAAElFTkSuQmCC" />
<feTile />
<feDisplacementMap in="SourceGraphic" xChannelSelector="G" yChannelSelector="R" scale="1" result="pxl" />

<!-- Map all color channel values <0.25 to 0, and >0.33 to 0.5 -->
<feColorMatrix type="matrix" in="pxl" values="1 0 0 0 -0.33 0 1 0 0 -0.33 0 0 1 0 -0.33 0 0 0 1 0" />
<feColorMatrix type="matrix" values="10000 0 0 0 0 0 10000 0 0 0 0 0 10000 0 0 0 0 0 1 0" />
<feColorMatrix type="matrix" values="0.5 0 0 0 0 0 0.5 0 0 0 0 0 0.5 0 0 0 0 0 1 0" result="halftones" />

<!-- Map all color channel values <0.66 to 0 and >0.75 to 1 -->
<feColorMatrix type="matrix" in="pxl" values="1 0 0 0 -0.66 0 1 0 0 -0.66 0 0 1 0 -0.66 0 0 0 1 0" />
<feColorMatrix type="matrix" values="10000 0 0 0 0 0 10000 0 0 0 0 0 10000 0 0 0 0 0 1 0" />

<!-- Add the two together -->
<feComposite in2="halftones" operator="arithmetic" k2="1" k3="1" />

This effect uses displacement map filter to make the image 2x2 pixel squares, for the retro feeling and abuses color matrix result clamping to reduce colors so that channel values can be only 0, 0.5 or 1, i.e. 27 different colors. This quantization can also be achieved using feComponentTransfer with big lookup tables for each feFunc[RGB].

And last, probably also the least, even simpler times:

ascii

Check the source if you want to see how it is made, essentially using the same tricks as in the retro filter, but making the tiles 8x16 and instead of using the quantized color values, use images of 8x16 console font characters to get a ascii art-ish result. This can be made pixel-perfect on firefox, but to have it also working in chrom(ium) at least somehow, some characters appear distorted.