Lekcja 11. Filtry

wrz 3, 2026 | Kurs SVG

Jedyne miejsce w SVG, gdzie przeglądarka generuje piksele od zera

Wszystko, co robiliśmy do tej pory, było opisem geometrii. Kształt, kontur, kolor — instrukcje, co narysować. Filtry działają na innym poziomie: biorą gotowy, wyrenderowany obraz i przetwarzają go piksel po pikselu.

To jest paradoks tego formatu. SVG jest wektorowe, ale filtry są operacjami rastrowymi. Dzięki temu ten sam plik, który waży dwa kilobajty, potrafi wygenerować rozmycie, cień, poświatę albo teksturę, której nikt nie narysował.

Budowa filtra

html

<defs>
  <filter id="cien">
    <feDropShadow dx="4" dy="6" stdDeviation="4"/>
  </filter>
</defs>

<rect ... filter="url(#cien)"/>

Schemat znasz już z gradientów: obiekt w <defs>, odwołanie przez url(#id). Nowe jest to, co siedzi w środku — prymitywy filtrujące, czyli elementy o nazwach zaczynających się od fe (od filter effect).

Jest ich kilkanaście. W praktyce używa się czterech, o których zaraz, a resztę rozpoznaje się w cudzych plikach.

Cień

Najczęściej używany filtr w całym webie.

html

<feDropShadow dx="4" dy="6" stdDeviation="4"
              flood-color="#0f0f0f" flood-opacity="0.35"/>

dx i dy przesuwają cień, stdDeviation steruje jego miękkością, a flood-opacity siłą. Zwróć uwagę, że rozmycie nie powiększa cienia — rozmywa jego krawędź, zostawiając środek na miejscu.

Warto wiedzieć, że feDropShadow to skrót. Zanim go wprowadzono, ten sam efekt składało się z czterech prymitywów: rozmycia, przesunięcia, wypełnienia kolorem i złożenia z oryginałem. Dziś to jedna linijka, ale w starszych plikach nadal spotkasz wersję rozpisaną.

Pułapka: obszar filtra

To jest błąd numer jeden przy filtrach i wygląda dokładnie jak awaria przeglądarki.

Filtr działa w ograniczonym prostokącie. Domyślnie jest to obszar kształtu powiększony o 10% z każdej strony. Wszystko, co wyjdzie poza — ucięte.

Przy cieniu przesuniętym o 20 jednostek i rozmytym o 8 ten zapas nie wystarcza. Efekt: cień jest przycięty w połowie, prostą, pionową krawędzią. Wygląda to na tyle nienaturalnie, że ludzie szukają błędu w geometrii, a wystarczy powiększyć obszar:

html

<filter id="cien" x="-40%" y="-40%" width="180%" height="180%">

Wartości ujemne w x i y przesuwają początek obszaru na zewnątrz kształtu, a width powyżej 100% go poszerza. To ta sama pułapka co przy maskach z poprzedniej lekcji — i to samo lekarstwo.

Nie warto jednak przesadzać w drugą stronę. Obszar filtra to realny bufor w pamięci; ustawienie go na 500% każe przeglądarce liczyć kilkanaście razy więcej pikseli, niż potrzeba.

Potok, nie pojedynczy efekt

Filtr może zawierać wiele prymitywów, a wtedy działają one jeden po drugim: wynik pierwszego jest wejściem drugiego.

html

<filter id="kolor">
  <feColorMatrix type="saturate" values="1.8"/>
  <feColorMatrix type="hueRotate" values="90"/>
</filter>

Najpierw zmienia się nasycenie, potem obrót barwy — na już zmienionym obrazie. Zamień suwaki miejscami w kodzie, a przy skrajnych wartościach wynik będzie inny, bo kolejność w potoku ma znaczenie tak samo jak przy transformacjach.

Gdy potrzebujesz czegoś bardziej rozgałęzionego, każdy prymityw może nazwać swój wynik atrybutem result i pobrać dowolne wejście przez in. Specjalna wartość SourceGraphic oznacza oryginalny, nieprzetworzony obraz — dzięki niej można na przykład rozmyć kopię kształtu i złożyć ją z ostrym oryginałem.

Szum

I na koniec prymityw, który nie przetwarza obrazu, tylko tworzy go od zera.

feTurbulence generuje szum Perlina — proceduralną teksturę, tę samą, którą w grafice 3D robi się chmury, marmur i powierzchnię wody. Sam w sobie wygląda jak kolorowy szum. Ciekawy staje się dopiero w połączeniu z feDisplacementMap, który używa go do rozepchnięcia pikseli innego kształtu.

baseFrequency to gęstość szumu, numOctaves to liczba warstw szczegółu, a scale decyduje, jak mocno szum przesuwa piksele. Przy dużym rozproszeniu prostokąt przestaje być prostokątem.

Tak robi się efekt odręcznego rysunku, postrzępionej krawędzi papieru albo zniekształceń w stylu glitch. Wszystko z kilkunastu linijek tekstu, bez ani jednej grafiki źródłowej.

Filtry w CSS

Do najprostszych rzeczy nie musisz definiować niczego w SVG. CSS ma własne skróty, które działają na dowolnym elemencie:

css

.karta { filter: drop-shadow(0 6px 12px rgba(0,0,0,.25)); }
.ikona:hover { filter: saturate(1.5) hue-rotate(20deg); }
.tlo { filter: blur(6px); }

Warto znać jedną różnicę praktyczną. box-shadow rysuje cień prostokąta elementu, a drop-shadow cień jego rzeczywistego kształtu — łącznie z przezroczystością. Dlatego cień pod ikoną SVG albo pod PNG z wyciętym tłem robi się wyłącznie przez drop-shadow.

Do wszystkiego, co bardziej złożone niż rozmycie i cień, wracasz do <filter> w SVG. CSS nie ma odpowiednika dla potoku ani dla szumu.

Kiedy uważać

Filtry są kosztowne. Każdy z nich oznacza wyrenderowanie fragmentu do osobnego bufora i przeliczenie pikseli — a rozmycie o dużym promieniu jest jedną z najdroższych operacji, jakie przeglądarka wykonuje.

Trzy praktyczne zasady: nie animuj stdDeviation, bo każda klatka to przeliczenie całego bufora. Nie nakładaj filtrów na duże obszary, zwłaszcza na tła pełnoekranowe. I nie zakładaj, że filtr przetrwa eksport — wiele narzędzi do konwersji, w tym część generatorów PDF, ignoruje je albo rasteryzuje.

Podsumowanie

  • Filtr to obiekt w <defs> złożony z prymitywów fe*, przypinany przez filter="url(#id)".
  • Filtry działają na pikselach już wyrenderowanego obrazu, a nie na geometrii.
  • Domyślny obszar filtra to kształt plus 10% z każdej strony; wszystko poza nim jest ucinane.
  • Prymitywy tworzą potok — wynik jednego jest wejściem następnego; in i result pozwalają go rozgałęzić.
  • feDropShadow to skrót na cztery operacje; feColorMatrix zmienia barwy; feTurbulence generuje teksturę od zera.
  • CSS ma skróty blur()drop-shadow()saturate()drop-shadow uwzględnia kształt, box-shadow tylko prostokąt.
  • Filtry są drogie obliczeniowo i nie zawsze przeżywają konwersję do innych formatów.

To koniec bloku o wyglądzie. W następnym kształty zaczną się ruszać — zaczynamy od pytania, czym właściwie animować SVG, skoro są aż trzy niezależne sposoby.


Do wypróbowania: w presecie feDropShadow zmień obszar filtra na domyślny, czyli x="-10%" y="-10%" width="120%" height="120%", i ustaw przesunięcie na maksimum. Cień zostanie ucięty pionową krawędzią — zobaczysz na żywo błąd, przez który ludzie przepisują całą geometrię, zamiast poprawić cztery procenty.