SVG/Tutorials/Filter/Licht und Schatten

Aus SELFHTML-Wiki
< SVG‎ | Tutorials‎ | Filter
Wechseln zu: Navigation, Suche

Sie können HTML-Elementen sowohl mit der box-shadow-Eigenschaft als auch der drop-shadow()-Funktion des CSS-Filters einen Schatten geben, wobei diese zweite Möglichkeit auch für SVG-Elemente möglich ist.

In diesem Kapitel lernen Sie, wie Sie solche Filter aus mehreren primitiven Filtern selbst erzeugen. So werden feinere Abstimmungen möglich.

Erzeugen eines weiteren Objekts

Ein (Schlag)-Schatten ist ja ein mittels einer Lichtquelle erzeugtes Projektionsbild des im „Weg des Lichtes stehenden“ Gegenstands. Deshalb wird in einem ersten Schritt unsere Grafik verdoppelt.

feOffset

Der primitive Filter feOffset verschiebt eine Grafik. Er verhält sich also ähnlich wie transform:translate(), nur eben innerhalb eines Filters. In der Praxis wird feOffset häufig in Zusammenhang mit anderen Filtern verwendet, um einen Schatten zu erzeugen.

feOffset nutzt dazu folgende Attribute:

  • dx: waagerechte Verschiebung
  • dy: senkrechte Verschiebung

Für dx und dy sind auch negative Werte zulässig, um die Grafik nach links bzw. oben zu verschieben.


feMerge

Der primitive Filter feMerge fügt Ergebnisse verschiedener Urfilter oder Eingabekanäle zusammen. Die zusammenzufügenden Eingaben oder Ergebnisse werden jeweils im Kindelement feMergeNode notiert. Die Eingaben werden in der Reihenfolge übereinandergelegt, wie sie notiert sind. Anders als bei feBlend sind beliebig viele Ebenen möglich.

Verdopplung mit feOffset und feMerge ansehen …
<defs>
  <filter id="f1" x="0" y="0" width="200%" height="200%">
    <feOffset in="SourceGraphic" result="translatedObject"  dx="20" dy="20" />
    <feMerge>
      <feMergeNode in="f1"/>
      <feMergeNode in="SourceGraphic"/>
    </feMerge>
  </filter>
</defs>

<g transform="translate(250,0)">
 <use xlink:href="#doppeldecker" filter="url(#f1)"/>
 <text x="20" y="190">Verdoppelung mit feOffset</text>
</g>

Der Filter besteht aus einem feOffset-Filter, der aus der Urspungsgrafik ein weiteres Bild mit einer Verschiebung von 20px in die x- und y-Richtung erzeugt.

Dieses wird mittels des feMerge-Filters wieder mit der Ursprungsgrafik zusammengeführt.


Unschärfe

feGaussianBlur

Durch die Streuung des Sonnenlichts in der Luft und die Reflektion von hellen Flächen ist ein Schatten aber nie so abgegrenzt wie im obigen Beispiel, sondern hat nur verschwommene Konturen. Mit dem feGaussianBlur-Filter, dem so genannten „Gausschen Weichzeichner“ können Sie die Ursprungsgrafik nun verwischen.

Beispiel ansehen …
<defs>
  <filter id="f1" x="0" y="0" width="200%" height="200%">
    <feOffset in="SourceGraphic" result="translatedObject"  dx="20" dy="20" />
    <feGaussianBlur in="translatedObject" result="blurredObject"  stdDeviation="10" />
    <feBlend in="SourceGraphic" in2="blurredObject" mode="normal" />
  </filter>
</defs>

<g transform="translate(250,0)">
 <use xlink:href="#doppeldecker" filter="url(#f1)"/>
 <text x="20" y="190">Verwischen mit feGaussianBlur </text>
</g>

Das Ergebnis des feOffset-Filters wird mit dem feGaussianBlur-Filter verwischt, sodass es nur noch verschwommen ist.

Die Ausgangsgrafik blurredObject wird mittels des feBlend-Filters wieder mit der Urspungsgrafik zusammengeführt.

Schattenfarbe

Farbige Schatten sind eher ein Sonderfall unter speziellen Lichtverhältnissen. Um unseren Schatten grau einzufärben gibt es zwei alternative Vorgehensweisen:

Beispiel ansehen …
<defs>
    <feOffset in="SourceAlpha" result="translatedObject"  dx="20" dy="20" />
	<feGaussianBlur in="translatedObject" result="blurredObject"  stdDeviation="10" />
    <feBlend in="SourceGraphic" in2="blurredObject" mode="normal" />
  </filter>
  
  <filter id="f2" x="0" y="0" width="200%" height="200%">
    <feOffset in="SourceGraphic" result="translatedObject"  dx="20" dy="20" />
    <feColorMatrix in="translatedObject" result="matrixOut" type="matrix"
               values="0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0" />
    <feGaussianBlur in="matrixOut" result="blurOut" stdDeviation="10" />
    <feBlend in="SourceGraphic" in2="blurOut" mode="normal" />	
  </filter>  
</defs>

Im linken Beispiel wird anstelle der Ausgangsgrafik selbst nur der Alphakanal der Ausgangsgrafik verwendet. <feOffset in="SourceAlpha" .../>

Im rechten Beispiel wird das Ergebnis der Verschiebung mit feOffset durch den feColorMatrix-Filter gefärbt. Durch die Multplikation der Farbwerte für rot, grün und blau werden sie dunkler und schwärzer. Alternativ könnte man hier den feFlood-Filter verwenden.

feDropShadow

Da bei den meisten Schlagschatten diese Schritte nötig sind, wurde im Filter Effects Module ein zusammenfassender Urfilter feDropShadow eingeführt, der alle obigen Schritte beinhaltet:


Neben den schon oben eingeführten

  • dx und dy für die Verschiebung
  • stdDeviation für den Weichzeichner-Effekt

gibt es die aus feFlood bekannten Präsentationsattribute

feDropShadow ansehen …
    <filter id="DropShadow">
      <feDropShadow dx="-0.8" dy="-0.8" stdDeviation="1"
          flood-color="pink" flood-opacity="0.5"/>
    </filter>

Schlaglicht und Innenschatten

Beleuchtete Objekte werfen aber nicht nur einen Schlagschatten auf den Hintergrund, sondern erscheinen im Schlaglicht heller und auf der abgewandten, aber sichtbaren Seite dunkler.


Beispiel ansehen …
	<radialGradient id="gold" cx="0.3" cy=".3" r=".5" >
		<stop offset="0%" stop-color="#fff" />
		<stop offset="100%" stop-color="gold" />
	</radialGradient>
	
	<filter id="InnerShadow">
		<feOffset dx="-20" dy="-20" />
		<feGaussianBlur stdDeviation="10" result="blurOut"/>
		<feComposite in="SourceGraphic" in2="blurOut" operator="out" result="inverseOut"/>
		<feFlood flood-color="black" flood-opacity="0.75" result="color" />
		<feComposite in="color" in2="inverseOut" operator="in" result="shadow"/>
		<feComposite in="shadow" in2="SourceGraphic" operator="over" />
	</filter>

Der Apfel und die Birne erhalten als Füllung einen radialGradient, der die beleuchtete Fläche weiß darstellt. Sie verläuft in die jeweilige Grundfarbe.

Zusätzlich können Sie mit dem InnerShadow-Filter Teile der Urspungsgrafik schattieren.

Wenn Sie die Ursprungsgrafik sowohl innen als auch außen schattieren wollen, müssen Sie beide Filter innerhalb eines Filterelements notieren und zum Schluss mit feBlend wieder zusammenführen. Ein Aufrufen mehrerer Filter ist in SVG leider nicht möglich.


Beleuchtungseffekte

Mit feGaussianBlur erzeugte Schlagschatten können aber auch als Ausgangspunkt für einen Beleuchtungseffekt mit dem feSpecularLighting-Filter verwendet werden. Der Wischeffekt des Schattens sorgt für eine abgerundete Oberfläche der Alphawerte, die durch den Beleuchtungseffekt hervorgehoben werden.

feDiffuseLighting

Der primitive Filter feDiffuseLighting dient der indirekten Beleuchtung durch diffuses Licht nach dem Phong-Modell. Als Lichtquellen dienen die Kindelemente feDistantLight (entfernte Lichtquelle), fePointLight (Punktlichtquelle) und feSpotLight (Scheinwerfer).

Folgende Attribute sind möglich:

  • in: Eingangsgrafik
  • surfaceScale: legt die Höhe der Oberfläche fest, auf die ein Beleuchtungs-Filter angewendet wird
  • diffuseConstant: repräsentiert den kd-Wert im Phong-Beleuchtungsmodell


indirekte Beleuchtung ansehen …
  <filter id="beleuchtung1">
    <feDiffuseLighting in="SourceGraphic" result="light" lighting-color="white">
      <feDistantLight azimuth="50" elevation="50"/>
    </feDiffuseLighting>

    <feComposite in="SourceGraphic" in2="light"
                 operator="arithmetic" k1="1" k2="0" k3="0" k4="0"/>
  </filter>
  
  <filter id="beleuchtung2">
    <feDiffuseLighting in="SourceGraphic" result="light" lighting-color="white">
      <fePointLight x="30" y="30" z="20" />
    </feDiffuseLighting>
    <feComposite in="SourceGraphic" in2="light"
                 operator="arithmetic" k1="1" k2="0" k3="0" k4="0"/>
  </filter>
  
 <filter id="beleuchtung3">
    <feDiffuseLighting in="SourceGraphic" result="light" lighting-color="white">
      <feSpotLight x="-20" y="5" z="30" limitingConeAngle="20"
                   pointsAtX="50" pointsAtY="50" pointsAtZ="0"/>
    </feDiffuseLighting>

    <feComposite in="SourceGraphic" in2="light"
                 operator="arithmetic" k1="1" k2="0" k3="0" k4="0"/>
  </filter>

Im Beispiel werden verschiedene Beleuchtungsfilter angewandt. Zuerst wird die Grafik mit einem feDiffuseLighting-Filter beleuchtet. Danach wird die Grafik mittels feComposite mit der Ursprungsgrafik kombiniert.

Um die Werte für die Lichtquellen nicht immer anpassen zu müssen, werden die Filter und Objekte auf den Ursprung (0,0) ausgerichtet und mit transform="translate() verschoben.

Die Beispiele in der 2. Spalte werden mit feDistantLight indirekt beleuchtet. Dabei fällt auf, dass sie dunkler als die unbeleuchteteten Elemente in der linken Spalte wirken. Durch eine Erhöhung des elevation-Werts auf 100 können Sie die Helligkeit verstärken.

Die Beispiele in der 3. Spalte werden mit fePointLight mit einer Punktlichtquelle beleuchtet.

Die Beispiele in der rechten Spalte werden mit feSpotLight mit einem Scheinwerfer beleuchtet.

Beachten Sie: Der Beleuchtungseffekt wird umso deutlicher, je heller das zu beleuchtende Objekt ist. Bei der Füllfarbe schwarz ist gar kein Beleuchtungseffekt zu erkennen.


Kindelemente

feDistantLight

Der Filter feDistantLight beleuchtet mit einer entfernten Lichtquelle.

Folgende Attribute sind nötig:

  • azimuth: Richtungswinkel der Lichtquelle
  • elevation: legt den Richtungswinkel (in Grad) der Lichtquelle aus der X,Y- Ebene zur Z-Achse fest

fePointLight

Der Filter fePointLight beleuchtet mit einer Punktlichtquelle.

Folgende Attribute sind möglich:

  • x: Koordinate der X-Achse
  • y: Koordinate der Y-Achse
  • Z: Koordinate der Z-Achse (Höhe der Lichtquelle)

Falls die Attribute nicht definiert werden, wird ein Wert von 0 angenommen.

feSpotLight

Der Filter feSpotLight beleuchtet mit einem Scheinwerfer.

Folgende Attribute sind möglich:

  • x: Koordinate der X-Achse
  • y: Koordinate der Y-Achse
  • Z: Koordinate der Z-Achse
  • limitingConeAngle: (Standardwert: kein Winkel) legt den Winkel (in Grad) der Beleuchtungsachse ( zwischen der Lichtquelle und dem beleuchteten Punkt) fest
  • pointsAtX: X-Position im Koordinatensystem
  • pointsAtY: Y-Position im Koordinatensystem
  • pointsAtZ: Z-Position im Koordinatensystem
  • specularExponent: legt den Fokus (Brennpunkt) der Lichtquelle fest (Standardwert:1)

Falls die Attribute nicht definiert werden, wird ein Wert von 0 angenommen.

Siehe auch


feSpecularLighting

Der primitive Filter feSpecularLighting dient der Beleuchtung einer Eingangsgrafik mit reflektierendem Licht. Dabei wird der Alpha-Kanal der Eingangsgrafik als Relief verwendet. Als Lichtquellen dienen die Kindelemente feDistantLight (entfernte Lichtquelle), fePointLight (Punktlichtquelle) und feSpotLight (Schweinwerfer).

Sie können die Relieftiefe, die Intensität und den Glanz des Lichts durch Attribute beeinflussen.

Folgende Attribute sind möglich:

  • in: Eingangsgrafik
  • surfaceScale: legt die Höhe der Oberfläche fest, auf die ein Beleuchtungs-Filter angewendet wird
  • specularConstant: repräsentiert den ks-Wert im Phong-Beleuchtungsmodell
  • specularExponent: legt den Fokus (Brennpunkt) der Lichtquelle fest (größerer Wert wirkt glänzender)


Beleuchtungseffekte ansehen …
<filter id="specular1">
  <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
  <feSpecularLighting in="blur" surfaceScale="5" specularConstant="1" 
          specularExponent="10" lighting-color="white" result="specOut">
    <fePointLight x="-50" y="-100" z="200"/>
  </feSpecularLighting>
  <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
  <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
                 k1="0" k2="1" k3="1" k4="0" result="out2"/>
  <feMerge>
    <feMergeNode in="out2"/>
  </feMerge>
</filter>
  
<filter id="specular2">
  <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
  <feSpecularLighting in="blur" surfaceScale="5" specularConstant="1"
                      specularExponent="10" lighting-color="white"  result="specOut">
    <feDistantLight azimuth="45" elevation="45"/>
  </feSpecularLighting>
  <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
  <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
                 k1="0" k2="1" k3="1" k4="0" result="out2"/>
  <feMerge>
    <feMergeNode in="out2"/>
  </feMerge>
</filter>

<filter id="specular3">
  <feGaussianBlur in="SourceAlpha" stdDeviation="4" result="blur"/>
  <feSpecularLighting in="blur" surfaceScale="5" specularConstant="1" 
        specularExponent="10" lighting-color="white" result="specOut">
    <feSpotLight x="-20" y="5" z="30" limitingConeAngle="45"
           pointsAtX="10" pointsAtY="10" pointsAtZ="0"/>
  </feSpecularLighting>
  <feComposite in="specOut" in2="SourceAlpha" operator="in" result="specOut"/>
  <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" 
                 k1="0" k2="1" k3="1" k4="0" result="out2"/>
  <feMerge>
    <feMergeNode in="out2"/>
  </feMerge>
</filter>

Im Beispiel werden verschiedene Beleuchtungsfilter angewandt. Zuerst wird die Grafik mit einem feSpecularLighting-Filter beleuchtet. Danach wird die Grafik mittels feComposite mit der Ursprungsgrafik kombiniert.

Die linke Spalte wird mit feDistantLight indirekt beleuchtet.

Die Objekte in der mittleren Spalte werden mit fePointLight mit einer Punktlichtquelle beleuchtet. Die Lichtquelle ist schräg über den Objekten platziert. (Verändern Sie die Werte für x, y und z!)

Die Beispiele in der rechten Spalte werden mit feSpotLight mit einem Scheinwerfer beleuchtet. Wie bei feDiffuseLighting ist hier kein ausgeprägter Lichtkegel sichtbar.


Weblinks

Siehe auch

Quellen