Podstawy antyaliasingu

Wstęp

Antyaliasing to jeden z najpowszechniejszych aspektów grafiki internetowej. To dlatego na ekranach jest wyświetlany czysty tekst i gładkie kształty wektorowe. Obecnie w przeglądarkach stosuje się kilka podejść do antialiasingu, które są najbardziej oczywiste w przypadku renderowania tekstu. Algorytm używany do wygładzania przełączników może prowadzić do nieoczekiwanych wyników wizualnych. W tym artykule przyjrzymy się różnym sposobom antyaliasing i zobaczymy, jak piksele są rysowane.

Każdy z naszych ekranów składa się, jak wszyscy wiemy, z pikseli. To olbrzymia siatka bloków, z których każdy zawiera czerwone, zielone i niebieskie komponenty (RGB). Z daleka widać obrazy, tekst i ikony, ale z bliska widać siatkę komponentów RGB i strukturę wszystkich elementów.

Zbliżenie na piksele ekranu. Każdy piksel ma komponenty czerwone, zielonego i niebieskiego.
Rysunek 1. Zbliżenie na piksele ekranu. Każdy piksel ma komponenty czerwone, zielone i niebieskie.

Antyaliasing

Co się stanie, gdy rysujemy kształt wektorowy, który przechodzi przez „część” piksela? Załóżmy, że rysowany przez nas kształt jest czarny, a tło jest białe. Czy powinniśmy pokolorować ten piksel w ogóle? Jakiego koloru ma być kolor, jeśli go pokolorujemy? Czarny czy szary, czy coś innego?

Proces antialiasingu określa, którego koloru należy użyć podczas wypełniania pikseli. Najprostsza wersja tego rozwiązania to antyaliasing w skali szarości. W jego przypadku 3 komponenty pikseli są traktowane jednakowo. Jeśli więc piksel jest w połowie zakryty (i przyjmijmy, że przez sekundę czarny tekst na białym tle jest prosty), można uznać, że każdy komponent będzie miał połowę jasności (wiem na pewno tak), ale tak naprawdę problem jest bardziej skomplikowany: trzeba uwzględnić współczynnik gamma, co oznacza, że prawdopodobnie nigdy nie ustawisz wartości tej dokładnej wartości. To oczywiście bywa nieco skomplikowane, ale ponieważ jest to wprowadzenie do tematu, nie będę o tym w tym miejscu zagłębiać. Warto wiedzieć, że antyaliasing funkcjonuje na poziomie piksela i w rzeczywistości możemy to robić znacznie lepiej.

Rys. 2. Wygładzanie krawędzi a twarde krawędzie
Rysunek 2. Z antyaliasem a twarde krawędzie

Na Rysunku 2 widać rysowany ten sam trójkąt, ale po lewej stronie jest włączone antyaliasing, a po prawej – wyłączony. Jak widać, po włączeniu antyaliasingu piksele są odcieniami szarości, gdy trójkąt przechodzi tylko przez część piksela. Gdy ta opcja jest wyłączona, piksel jest wypełniany czarnymi lub jednolicie białym obrazem, a kształt jest postrzępiony.

Renderowanie tekstu

Gdy przeglądarka renderuje tekst, który ma w zasadzie kształt wektorowy, napotkamy ten sam problem: znaki tekstu wypełnią tylko część pikseli, dlatego musimy opracować strategię wypełniania tych pikseli. Najlepiej jest nałożyć na tekst antyaliasing, aby czytał się go łatwiej i przyjemnie.

Okazuje się jednak, że podejście do antyaliasingu w skali szarości to tylko jeden ze sposobów radzenia sobie z tym problemem. Często wybierany jest sposób bardziej selektywny przy włączaniu komponentów RGB w pikselach. Proces ten jest nazywany antyaliasingiem subpikselowym. W szczególności zespół ClearType w firmie Microsoft włożył w jego rozwój wiele czasu i wysiłku. Teraz jest on powszechnie używany i wszystkie najpopularniejsze przeglądarki używają go w większym lub mniejszym stopniu.

Po pierwsze, ponieważ wiemy, że każdy piksel w rzeczywistości składa się z osobnych komponentów w kolorze czerwonym, zielonym i niebieskim, wykrywamy, jak dużo należy „włączyć” w przypadku danego piksela. Jeśli więc piksel jest „w połowie zakryty” z lewej strony, możemy w pełni włączyć czerwony komponent, zielony w połowie, a niebieski wyłączony. Ten proces jest często opisany jako „potrójny zwiększenie rozdzielczości poziomej ekranu” i polega na tym, że każdy piksel jest w rzeczywistości 3 osobnymi komponentami, a nie jedną.

Rys. 3. Antyaliasing w skali szarości i subpiksele
Rysunek 3. Antyaliasing w skali szarości a subpiksele

Na ilustracji 3 powyżej widać, że po lewej stronie każdy komponent traktujemy tak samo, a każdy z nich jest tak samo włączony lub wyłączony (tryb szarości). Po prawej stronie korzystamy jednak z podpiksela, więc każdy komponent (czerwony, zielony i niebieski) różni się w zależności od tego, jak bardzo nakładają się na rysowany kształt.

Jednak ludzki wzrok nie jest tak samo ważny dla światła czerwonego, zielonego i niebieskiego. Jesteśmy dużo bardziej wrażliwi na kolor zielony niż czerwony lub niebieski. Oznacza to, że chociaż antyaliasing ma wyraźną przewagę nad antyaliasingiem w skali szarości, jak zauważa Darel Rex Finley, włączenie każdego komponentu oddzielnie nie przyniesie trzykrotnie lepszej czystości. Antyaliasing podpikselowy jest jednak naprawdę pomocne i oznacza, że tekst jest wyraźniejszy niż w przypadku stosowania antyaliasingu w skali szarości.

Rys. 4. Tekst z antyaliasem w postaci subpiksela. Aby uzyskać ogólny efekt, włączone są poszczególne komponenty pikseli.
Rysunek 4. Tekst z antyaliasem w postaci subpikseli. Aby uzyskać ogólny efekt, włącz poszczególne komponenty pikseli.

Przejście do drogi

Co to oznacza dla nas, deweloperów? Patrząc z perspektywy Chrome, można stosować do renderowania tekstu zarówno w skali szarości, jak i subpikselach antyaliasing, a to, który z nich uzyska, zależy od kilku kryteriów. Na początek musimy jednak zrozumieć trochę kwestii warstw, ponieważ to jest główne kryterium w grze. Jeśli nie znasz jeszcze warstw i nie znasz sposobu, w jaki Chrome jest używany wewnętrznie, Tom Wiltzius napisał świetne wprowadzenie do tego tematu, z którym musisz się najpierw zapoznać.

Kontynuujmy, zakładając, że znasz się na warstwach lub o nich już czytasz. Jeśli w przypadku strony włączone jest komponowanie sprzętowe, a w warstwie, która nie jest warstwą główną, będzie domyślnie renderowana z użyciem antyaliasingu skali szarości. Programiści często zauważają, że jeśli stosują hakowanie do elementów i umieść je w warstwach innych niż główne (np. z użyciem translateZ), tekst będzie renderowany w różny sposób. Programiści często na bieżąco stosują reguły „nowej warstwy” w JavaScripcie lub CSS, powodując przełączenie renderowania tekstu z subpiksela na tryb szarości. Nie wiadomo, co spowodowało zmianę renderowania, więc może to być mylące. Jeśli jednak tekst znajduje się w warstwie głównej, powinien zostać wyrenderowany za pomocą antyaliasingu subpikselowego, dzięki czemu będzie bardziej czytelny.

Ale, tak jak wszystko w internecie, zmienia się. W Chrome włącza się antyaliasing subpikseli dla tekstu w warstwach innych niż główne, o ile warstwa spełnia 3 kryteria. Warto przyznać, że kryteria te obowiązują dzisiaj, ale prawdopodobnie ulegną zmianie i z czasem będziesz mieć więcej zgłoszeń. Obecnie kryteria te są następujące:

  1. Warstwa ma przezroczyste tło. W szczególności użycie parametru border-radius lub innej wartości background-clip sprawia, że warstwa jest traktowana jako nieprzezroczysta, a renderowanie tekstu powoduje przywrócenie wygładzania skali szarości.
  2. Warstwa może mieć wyłącznie przekształcenie tożsamości lub translację całkową. Całką nazywamy wartości zaokrąglone. Na przykład funkcja translate(20.2px, 30px) wywoła antyaliasing w skali szarości, ponieważ składnik x (20.2px) nie jest całką. Przekształcenie tożsamości oznacza po prostu, że poza wartością domyślną nie obowiązują żadne dodatkowe operacje rotacji, translacji ani skalowania.
  3. Nieprzezroczystość warstwy to 1,0. Każda zmiana przezroczystości spowoduje zmianę wygładzania z subpiksela na tryb szarości.
Rysunek 5. Przed i po: tryb szarości a subpiksel Zwróć uwagę na kolorowe obramowanie tekstu po prawej stronie.
Rysunek 5. Przed i po: skalę szarości a subpiksel Zwróć uwagę na kolorowe obramowanie tekstu po prawej stronie

Ostatnią kwestią, o której warto pamiętać, jest to, że zastosowanie animacji CSS może spowodować utworzenie nowej warstwy, podczas gdy użycie właściwości requestAnimationFrame tego nie robi. Ze względu na różnice w renderowaniu tekstu niektórzy programiści nie mogli korzystać z animacji CSS. Jeśli więc używasz JavaScriptu do animowania elementów z powodu różnic w renderowaniu tekstu, sprawdź, czy ta aktualizacja Ci się przydaje.

To wszystko w Chrome. Jeśli chodzi o inne przeglądarki, Opera w miarę migracji do Chromium powinna ściśle odpowiadać działaniu Chrome. Wydaje się, że Internet Explorer używa antyaliasingu dla niemal całego tekstu (oczywiście przy włączonej funkcji ClearType), chociaż nie jest to możliwe w trybie Metro w Windows 8. Ze względu na bliskość ekranu Blink WebKit działa bardzo podobnie do Chrome, jednak bez tych nowszych ulepszeń, które umożliwiłyby szersze zastosowanie antyaliasingu. Przeglądarka Firefox działa w dużej mierze tak samo jak w Internet Explorerze – w przypadku praktycznie całego tekstu stosuje się antyaliasing subpikselowy. Oczywiście nie jest to wyczerpująca lista i prawdopodobnie w wszystkich przeglądarkach będzie stosowane antyaliasing w skali szarości zamiast subpiksela. Warto jednak wiedzieć, że antyaliasing subpikselowy jest powszechnie używany w głównych przeglądarkach.

Podsumowanie

Wiesz już trochę o tym, jak działa antyaliasing i dlaczego obecnie występują różnice w renderowaniu tekstu w witrynach i aplikacjach, zwłaszcza na urządzeniach o niższej rozdzielczości DPI. Jeśli chcesz śledzić implementację Chrome w zakresie renderowania tekstu, oznacz gwiazdką te błędy:

Materiały i źródła wiedzy