Search code examples
htmlcsssvggraphicssvg-filters

Why does converting my greyscale SVG to alpha cause a reduction in brightness?


I'm trying to create a transparent "starry night" effect with an SVG. I have my SVG inlined on a webpage, inside an element with a black background. I start out with a turbulence filter, then apply a color matrix to get the desired effect:

<svg xmlns="http://www.w3.org/2000/svg">
    <filter id="filter">
        <feTurbulence baseFrequency="0.2" />
        <feColorMatrix values="
            0 0 0 1 -.5
            0 0 0 1 -.5
            0 0 0 1 -.5
            0 0 0 0 1" />
    </filter>
    <rect width="100%" height="100%" filter="url(#filter)" />
</svg>

... which gives:

pic1

But this has no alpha transparency; I want this to represent a plane of white pixels whose brightness is reduced only by being on a black background and having less opacity. So I put it through a second filter to do this:

<svg xmlns="http://www.w3.org/2000/svg">
    <filter id="filter">
        <feTurbulence baseFrequency="0.2" />
        <feColorMatrix values="
            0 0 0 1 -.5
            0 0 0 1 -.5
            0 0 0 1 -.5
            0 0 0 0 1" />
        <feColorMatrix values="
            0 0 0 0 1
            0 0 0 0 1
            0 0 0 0 1
            1 1 1 0 0" />
    </filter>
    <rect width="100%" height="100%" filter="url(#filter)" />
</svg>

... which gives:

img2

This is very similar, but slightly darker. Why is it slightly darker? Shouldn't it logically produce identical pixel colours when overlayed on a black background?


Solution

  • As Robert notes above, there is some weirdness produced by color space conversions. Pixels should actually be brighter after the second colormatrix. It looks like you can fix this by adding an additional feComponentTransfer with SQRT(1/2.2) as the exponent value.

    <filter id="filter" >
        <feTurbulence baseFrequency="0.2" />
         <feColorMatrix type="matrix" values="
            0 0 0 1 -.5
            0 0 0 1 -.5
            0 0 0 1 -.5
            0 0 0 0 1" />
        <feColorMatrix type="matrix" values="
            0 0 0 0 1
            0 0 0 0 1
            0 0 0 0 1
            1 1 1 0 0" />
       <feComponentTransfer>
         <feFuncA type="gamma" exponent="0.674"/>
      </feComponentTransfer>
    </filter>