Search code examples
firefoxsvgsvg-filters

svg noise not shown in firefox


Made up a cloudy svg background for my project. It works perfectly in MS Edge,in Google Chrome, it even works when placed as desktop background in XFCE. But it ain`t working in Firefox. Neither under Win, nor Linux. Maybe there is some crutch needed?

<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">      
<defs>
 <radialGradient id="Background"  cx="50%" cy="50%" r="120%">
     <stop offset="0%" stop-opacity="1" stop-color="#369" />
     <stop offset="170%" stop-opacity="1" stop-color="#000"/>
   </radialGradient>  
   <filter id="noise" x="0" y="0" width="100%" height="100%">   
     <feImage xlink:href="#bkgrad" result="image" x="0" y="0"/>    
     <feTurbulence  baseFrequency="0.001" seed="999" type="fractalNoise" numOctaves="8" result="fnoise"/>        
     <feColorMatrix   in="fnoise" result="snoise"
                 type="saturate"
                 values="0" />    
     <feBlend in="SourceGraphics" in2="snoise" mode="multiply"></feBlend>
     <feBlend in="snoise" in2="image" mode="multiply"></feBlend>
    </filter> 
    <polyline id="Hexagon" stroke="#000" stroke-opacity="0.15" fill="none" stroke-width = "1.2px"
       points="0,0 8,0 12,6.9 8,13.8 0,13.8 8,13.8 12,6.9 20,6.9 24,13.8 20,6.9 24,0 32,0 "/>
    <pattern id="Hex_Pattern" patternUnits="userSpaceOnUse" patternTransform="translate(0,0)"
      width="24" height="13.8" >
      <use xlink:href="#Hexagon"/>
    </pattern> 
</defs>
<rect x="0" y="0" width="100%" height="100%" fill="url(#Background)"  id="bkgrad" ></rect>
<rect x="0" y="0" width="100%" height="100%" style="filter:url('#noise')" fill="url(#Background)"/>
<rect x="0" y="0" width="100%" height="100%" fill="url(#Hex_Pattern)" id="hexes"/>
</svg>


Solution

  • The attribute value for the <feBlend> filter is in="SourceGraphic", not in="SourceGraphics". Firefox did not render the whole filter because of that error, while other browsers and renderers used a fallback and used the last filter result as first source, effectively multiplying the result of feColorMatrix with itself. (This behavior is new in the CSS filter spec, it was not defined in SVG 1.1.)

    Since the output of that part of the filter is never used anyway, remove it.

    Additionally, as Robert Longson pointed out, feImage does not support references to internal fragments in Firefox. But you don't really need it. The referenced image is identical to the source graphic for the filter, so you can simply remove that primitive and reroute the input to the other primitives:

    <svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%">      
    <defs>
     <radialGradient id="Background"  cx="50%" cy="50%" r="120%">
         <stop offset="0%" stop-opacity="1" stop-color="#369" />
         <stop offset="170%" stop-opacity="1" stop-color="#000"/>
       </radialGradient>  
       <filter id="noise" x="0" y="0" width="100%" height="100%">   
         <feTurbulence  baseFrequency="0.001" seed="999" type="fractalNoise" numOctaves="8" result="fnoise"/>        
         <feColorMatrix   in="fnoise" result="snoise"
                     type="saturate"
                     values="0" />    
         <feBlend in="snoise" in2="SourceGraphic" mode="multiply"></feBlend>
        </filter> 
        <polyline id="Hexagon" stroke="#000" stroke-opacity="0.15" fill="none" stroke-width = "1.2px"
           points="0,0 8,0 12,6.9 8,13.8 0,13.8 8,13.8 12,6.9 20,6.9 24,13.8 20,6.9 24,0 32,0 "/>
        <pattern id="Hex_Pattern" patternUnits="userSpaceOnUse" patternTransform="translate(0,0)"
          width="24" height="13.8" >
          <use xlink:href="#Hexagon"/>
        </pattern> 
    </defs>
    <rect x="0" y="0" width="100%" height="100%" style="filter:url(#noise)" fill="url(#Background)"/>
    <rect x="0" y="0" width="100%" height="100%" fill="url(#Hex_Pattern)" id="hexes"/>
    </svg>