Maybe I'm not understanding <feComposite/>
, but it seems it cannot be used in a following <feGaussianBlur/>
's in
- I can only use SourceGraphic
, which isn't what I want.
Basically, I have a filter that creates two shapes (one of the original path, but fills it with a color, and one of the original shape, but offsets and blurs it). I want to combine those two shapes into a 3rd one using <feComposite/>
, and then apply some more filter items to that third one (a blur). But the blur is applied to shapes #1 and #2, instead of the combined shape #3.
You can see the problem here:
<svg name="wave-shadow-glow" class="wave" x="25" y="25" width="108" height="108" overflow="visible"
stroke-width="4.5" fill="red" stroke="#00B0F0">
<defs>
<symbol id="maincontainereffects" overflow="visible">
<path d="M0,13.5 C 36,-31.5 72,58.5 108,13.5 L 108,94.5 C 72,139.5 36,49.5 0,94.5 Z "
filter="url(#mainFilter-effects0sp5)" stroke="none"></path>
</symbol>
<filter id="mainFilter-effects0sp5" color-interpolation-filters="sRGB" x="-100%" y="-100%" width="300%"
height="300%">
<!--shape #1. original, but make it black-->
<feColorMatrix in="SourceGraphic" type="matrix" values="
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" result="InnerShadowBlack"></feColorMatrix>
<!--shape #2. original, but offset it... -->
<feOffset in="SourceGraphic" dx="-30" dy="0" result="InnerSourceOffset"></feOffset>
<!--shape #2 cont. ...and blur it
(in reality, I don't want to blur it, but rather "feather" it, but...
that's a story for another day...) -->
<feGaussianBlur in="InnerSourceOffset" stdDeviation="4" result="InnerSourceBlurred"></feGaussianBlur>
<!--shape #3. combine the two above. don't need shapes #1 and #2 anymore-->
<feComposite operator="atop" in="InnerSourceBlurred" in2="InnerShadowBlack" result="InnerShadow">
</feComposite>
<!--shape #4. create a green blurred shape of shape #3 in order to put it behind shape #3 in the shape #5 merge-->
<!-- NOTE: this is where the problem comes from.
If I use "SourceGraphic" in "in", it works fine. But I can't use "InnerShadow" because
the glow will appear around shapes #1 and #2 seperately-->
<feGaussianBlur in="InnerShadow" stdDeviation="3.33" result="firstGlowBlur"></feGaussianBlur>
<feColorMatrix in="firstGlowBlur" type="matrix" values="0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 2 2 2 1 0"
result="firstColorMatrix">
</feColorMatrix>
<feGaussianBlur in="firstColorMatrix" stdDeviation="2.222" result="Glow"></feGaussianBlur> -->
<!--shape #5. merge shapes #3 and #4-->
<feMerge result="InnerShadowAndGlow">
<feMergeNode in="Glow"></feMergeNode>
<feMergeNode in="InnerShadow"></feMergeNode>
</feMerge>
</filter>
</defs>
<use id="maincontainerwitheffect" href="#maincontainereffects"></use>
</svg>
As noted though the first <feGaussianBlur/>
in shape #4 uses InnerShadow
, which is what I want, because I may start with a different shape than SourceGraphic
(i.e. before all all of these filter items, I may use something like an feMorphology
to make the first image smaller.
Using SourceGraphic
does work and produces the right result - it just isn't what a need for this filter - I need the glow around InnerShadow
.
<svg name="wave-shadow-glow" class="wave" x="25" y="25" width="108" height="108" overflow="visible"
stroke-width="4.5" fill="red" stroke="#00B0F0">
<defs>
<symbol id="maincontainereffects" overflow="visible">
<path d="M0,13.5 C 36,-31.5 72,58.5 108,13.5 L 108,94.5 C 72,139.5 36,49.5 0,94.5 Z "
filter="url(#mainFilter-effects0sp5)" stroke="none"></path>
</symbol>
<filter id="mainFilter-effects0sp5" color-interpolation-filters="sRGB" x="-100%" y="-100%" width="300%"
height="300%">
<!--shape #1. original, but make it black-->
<feColorMatrix in="SourceGraphic" type="matrix" values="
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" result="InnerShadowBlack"></feColorMatrix>
<!--shape #2. original, but offset it... -->
<feOffset in="SourceGraphic" dx="-30" dy="0" result="InnerSourceOffset"></feOffset>
<!--shape #2 cont. ...and blur it
(in reality, I don't want to blur it, but rather "feather" it, but...
that's a story for another day...) -->
<feGaussianBlur in="InnerSourceOffset" stdDeviation="4" result="InnerSourceBlurred"></feGaussianBlur>
<!--shape #3. combine the two above. don't need shapes #1 and #2 anymore-->
<feComposite operator="atop" in="InnerSourceBlurred" in2="InnerShadowBlack" result="InnerShadow">
</feComposite>
<!--shape #4. create a green blurred shape of shape #3 in order to put it behind shape #3 in the shape #5 merge-->
<!-- NOTE: this is where the problem comes from.
If I use "SourceGraphic" in "in", it works fine. But I can't use "InnerShadow" because the glow will appear around shapes #1 and #2 separately -->
<feGaussianBlur in="SourceGraphic" stdDeviation="3.33" result="firstGlowBlur"></feGaussianBlur>
<feColorMatrix in="firstGlowBlur" type="matrix" values="0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 2 2 2 1 0"
result="firstColorMatrix">
</feColorMatrix>
<feGaussianBlur in="firstColorMatrix" stdDeviation="2.222" result="Glow"></feGaussianBlur> -->
<!--shape #5. merge shapes #3 and #4-->
<feMerge result="InnerShadowAndGlow">
<feMergeNode in="Glow"></feMergeNode>
<feMergeNode in="InnerShadow"></feMergeNode>
</feMerge>
</filter>
</defs>
<use id="maincontainerwitheffect" href="#maincontainereffects"></use>
</svg>
Am I misunderstanding <feComposite/>
in that it can only be used to display, but can't be used in subsequent filter operations?
It is not the feComposite
that is responsible for the error, but the second feMatrix
. I don't get the math here completely, but this is what I see in Inkscape if I apply everything up to that filter primitive, before further blurring:
What you really wanted to do was color the shape green and widen the preexisting blur radius. That can be done with the matrix
0 0 0 0 0
0 0 0 0 1 <- add green
0 0 0 0 0
0 0 0 10 0 <- raise opacity
<svg name="wave-shadow-glow" class="wave" x="25" y="25" width="108" height="108" overflow="visible"
stroke-width="4.5" fill="red" stroke="#00B0F0">
<defs>
<symbol id="maincontainereffects" overflow="visible">
<path d="M0,13.5 C 36,-31.5 72,58.5 108,13.5 L 108,94.5 C 72,139.5 36,49.5 0,94.5 Z "
filter="url(#mainFilter-effects0sp5)" stroke="none"></path>
</symbol>
<filter id="mainFilter-effects0sp5" color-interpolation-filters="sRGB" x="-100%" y="-100%" width="300%"
height="300%">
<feColorMatrix in="SourceGraphic" type="matrix" values="
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 1 0" result="InnerShadowBlack"></feColorMatrix>
<feOffset in="SourceGraphic" dx="-30" dy="0" result="InnerSourceOffset"></feOffset>
<feGaussianBlur in="InnerSourceOffset" stdDeviation="4" result="InnerSourceBlurred"></feGaussianBlur>
<feComposite operator="atop" in="InnerSourceBlurred" in2="InnerShadowBlack" result="InnerShadow">
</feComposite>
<feGaussianBlur in="InnerShadow" stdDeviation="3.33" result="firstGlowBlur"></feGaussianBlur>
<feColorMatrix in="firstGlowBlur" type="matrix" values="
0 0 0 0 0
0 0 0 0 1
0 0 0 0 0
0 0 0 10 0" result="firstColorMatrix"></feColorMatrix>
<feGaussianBlur in="firstColorMatrix" stdDeviation="2.222" result="Glow"></feGaussianBlur>
<feMerge result="InnerShadowAndGlow">
<feMergeNode in="Glow"></feMergeNode>
<feMergeNode in="InnerShadow"></feMergeNode>
</feMerge>
</filter>
</defs>
<use id="maincontainerwitheffect" href="#maincontainereffects"></use>
</svg>