W tym artykule Valve Distance Fields (SDF) zostało przedstawione jako szybkie rozwiązanie umożliwiające niezależne od rozdzielczości renderowanie czcionek przez Valve .
Mam już działające rozwiązanie Valve, ale chciałbym zachować ostrość na rogach. Valve twierdzi, że ich metoda pozwala osiągnąć ostre rogi za pomocą drugiego kanału teksturowego ANDed z podstawowym, ale brakuje wyjaśnienia, w jaki sposób ten drugi kanał zostałby wygenerowany.
W rzeczywistości w tym dokumencie pozostało wiele szczegółów implementacyjnych.
Chciałbym wiedzieć, czy ktoś z was mógłby wskazać mi kierunek, w jaki sposób renderować czcionki SDF z ostrymi narożnikami.
texture
signed-distance-field
font-rendering
Felipe Lira
źródło
źródło
Odpowiedzi:
Adam Simmons wykonał kilka interesujących prac w tej dziedzinie. Nie wiem dokładnie, jak to osiąga, ale jego rendering wektorowy oparty na SDF jest najostrzejszy, jaki widziałem w praktyce poza Valve. http://twitter.com/adamjsimmons/status/611677036545863680
źródło
EDYCJA: Proszę zobaczyć moją drugą odpowiedź z konkretnym rozwiązaniem.
Dokładnie rozwiązałem ten problem ponad rok temu w pracy magisterskiej. W dokumencie Valve pokazują, że możesz ORAZ dwa pola odległości, aby to osiągnąć, co działa, dopóki masz tylko jeden wypukły narożnik. W przypadku wklęsłych narożników potrzebujesz również operacji OR. Ten facet opracował niejasny system przełączania między dwiema operacjami za pomocą czterech kanałów tekstur.
Istnieje jednak znacznie prostsza operacja, która może ułatwić zarówno AND, jak i OR, w zależności od sytuacji, i to jest główna idea mojej tezy: mediana trzech . Zasadniczo używasz dokładnie trzech kanałów (idealnych dla RGB), które są całkowicie wymienne, i łączysz je za pomocą operacji mediany (wybierz środkową wartość z trzech).
Aby dostosować się do wygładzania, nie pracujemy tylko z wartościami logicznymi, ale wartościami zmiennoprzecinkowymi, a operacja AND staje się minimum, a OR staje się maksymalnie dwiema wartościami. Mediana trzech może rzeczywiście zrobić oba: jeśli a < b , dla ( a , a , b ), mediana jest minimalna, a dla ( a , b , b ) jest maksymalna.
Proces renderowania jest nadal niezwykle prosty. Cały moduł cieniujący fragmenty wraz z wygładzaniem może wyglądać mniej więcej tak:
Tak więc jedyną różnicą w stosunku do oryginalnej metody jest obliczenie mediany zaraz po próbkowaniu tekstury. Trzeba będzie jednak zaimplementować funkcję mediany, co można zrobić za pomocą zaledwie 4 min / maks . Operacji .
Teraz oczywiście pytanie brzmi: jak zbudować takie trzykanałowe pole odległości?I to jest trudna część. Najbardziej oczywistym podejściem, które podjąłem na początku, było rozłożenie wejściowego kształtu / glifu na trzy składniki, a następnie wygenerowanie konwencjonalnego pola odległości z każdego z nich. Zasady tego rozkładu nie są tak skomplikowane. Po pierwsze, obszar z co najmniej 2 z 3 kanałami jest wewnątrz. Następnie, jeśli wyobrażasz to sobie jako kanały kolorów RGB, wypukłe rogi muszą być wykonane z drugiego koloru, a jego dwa podstawowe elementy muszą być skierowane na zewnątrz. Wklęsłe rogi są odwrotne: dwa kolory wtórne otaczają ich wspólny kolor podstawowy, a klin między miejscem, w którym obie krawędzie są skierowane do wewnątrz, jest biały. Zauważyłem również, że konieczne jest wypełnienie, gdy dwa kolory podstawowe lub dwa kolory wtórne dotknęłyby się, aby uniknąć artefaktów (na przykład w środkowym obrysie litery „N”
Poniższy obraz to przykładowy rozkład wygenerowany przez program na podstawie mojej tezy:
Takie podejście ma jednak pewne wady. Jednym z nich jest to, że efekty specjalne, takie jak kontury i cienie, nie będą już działać poprawnie. Na szczęście wymyśliłem także drugą, znacznie bardziej elegancką metodę, która generuje pola odległości bezpośrednio, a nawet obsługuje wszystkie efekty graficzne. Jest to również uwzględnione w mojej pracy magisterskiej, a więc ma też ponad rok. Nie zamierzam teraz podawać więcej szczegółów, ponieważ obecnie piszę artykuł szczegółowo opisujący tę drugą technikę, ale opublikuję ją tutaj, jak tylko się skończy.
Tak czy inaczej, oto przykład różnicy w jakości. Rozdzielczość tekstury jest taka sama na każdym obrazie, ale lewa używa zwykłej tekstury, środkowa używa zwykłego pola odległości, a prawa używa mojego trzykanałowego pola odległości. Narzut wydajnościowy to tylko różnica między próbkowaniem tekstury RGB a monochromatyczną.
źródło
Przepraszam za długie oczekiwanie, ale stało się oczywiste, że chociaż obiecany artykuł jest w zasadzie kompletny, proces publikacji zajmie trochę czasu. Dlatego zamiast tego przygotowałem program open source z moim nowym wielokanałowym algorytmem budowy pola odległości, msdfgen , który możesz wypróbować już teraz.
Jest dostępny na GitHub: https://github.com/Chlumsky/msdfgen
(Jestem nowy, więc daj mi znać, jeśli coś jest nie tak z repozytorium).
Ktoś zapytał również o to, jak wypada w porównaniu z większym monochromatycznym polem odległości, więc tutaj jest zwiastun różnicy jakości. Jednak tak naprawdę zależy to od konkretnej czcionki i nie powiedziałbym, że zawsze jest to warte dodatkowych danych.
źródło
Dość ciekawe! Jestem autorem papieru dystansowego z zaworem. Przepraszam, że jest to trochę rzadkie w szczegółach implementacji. Jako przyszłą pracę podałem tylko przykład z dwoma kanałami - nie miałem generatora. Doszedłem do wniosku, że generowanie sdf o wysokiej rozdzielczości, a następnie segmentacja na podstawie kąta gradientu sdf byłoby rozsądną taktyką. Ale nigdy do tego nie doszło. Każdy schemat wielokanałowy należy porównać z wykorzystaniem danych jednokanałowych o wyższej rozdzielczości o tej samej powierzchni pamięci, aby uzyskać współczynniki powiększenia wymagane przez aplikację.
źródło
W żadnym wypadku nie jestem ekspertem w tej dziedzinie, ale możesz teoretycznie zachować ostre rogi w monochromatycznym pseudo-SDF, jeśli użyjesz albo filtra dwustronnego, kierunkowego filtra dwububkowego zamiast standardowego filtra dwuliniowego. Oprócz oczywistej korzyści z oszczędzania pamięci, możesz również mieć wiele kanałów dla wielokolorowych naklejek SDF.
Alternatywnie, jeśli nie masz nic przeciwko użyciu drugiego kanału, możesz również spróbować mieć jeden kanał dla odległości poziomej, a drugi dla odległości pionowej, i użyć piramidy energetycznej Różnica Laplaceana (DoL) do skompresowania tekstury, aby nadmiarowe informacje nie były nie będą rejestrowane.
Trzecim i ostatnim teoretycznym rozwiązaniem byłoby eksperymentowanie z teksturą próbkowaną sześciokątnie za pomocą adresowania zestawu macierzy.
Niestety, nie mam obecnie środków do testowania moich pomysłów i nie mogłem znaleźć żadnych dokumentów opisujących lub testujących coś podobnego do moich pomysłów. Wkrótce dołączę wszystkie odpowiednie artykuły, do których otrzymałem informacje / pomysły.
źródło