Podczas zmniejszania głębi kolorów i ditheringu za pomocą 2-bitowego szumu (przy n =] 0,5,1,5 [i wyjściowego = floor (wejście * (2 ^ bity-1) + n)), końce zakresu wartości (wejścia 0,0 i 1,0 ) są głośne. Pożądane byłoby, aby miały jednolity kolor.
Przykład: https://www.shadertoy.com/view/llsfz4
(powyżej jest zrzut ekranu shadertoy, przedstawiający gradient i oba końce, które powinny być odpowiednio białe i czarne, ale zamiast tego są głośne)
Problem można oczywiście rozwiązać, po prostu kompresując zakres wartości, aby końce były zawsze zaokrąglane do pojedynczych wartości. To trochę hack i zastanawiam się, czy istnieje sposób na wdrożenie tego „poprawnie”?
image-processing
noise
hotmultimedia
źródło
źródło
Odpowiedzi:
TL; DR: dithering trójkątny-pdf 2 * 1LSB przerywa edgecases w 0 i 1 z powodu zaciśnięcia. Rozwiązaniem jest lerp do jednobitowego ditheringu w tych edgecases.
Dodaję drugą odpowiedź, ponieważ okazało się to nieco bardziej skomplikowane niż początkowo myślałem. Wygląda na to, że ten problem to „DO ZROBIENIA: wymaga mocowania?” w moim kodzie, odkąd przeszedłem ze znormalizowanego na trójkątny dithering ... w 2012 roku. Dobrze jest w końcu na to spojrzeć :) Pełny kod dla rozwiązania / obrazów używanych w całym poście: https://www.shadertoy.com/view/llXfzS
Po pierwsze, oto problem, na który patrzymy, przy kwantyzacji sygnału do 3 bitów przy ditheringu trójkątnym-pdf 2 * 1LSB:
- zasadniczo to, co pokazała hotmultimedia.
Zwiększając kontrast, efekt opisany w pytaniu staje się widoczny: Moc wyjściowa nie jest średnia do czerni / bieli w krawędziach (i faktycznie wykracza znacznie poza 0/1 przed zrobieniem tego).
Spojrzenie na wykres zapewnia nieco więcej wglądu:
(szare linie oznaczają 0/1, również szary jest sygnałem, który próbujemy wyprowadzić, żółta linia jest średnią z rozłożonego / skwantowanego wyjścia, czerwona to błąd (średni sygnał)).
Co ciekawe, nie tylko średnia moc wyjściowa nie wynosi 0/1 na granicach, ale także nie jest liniowa (prawdopodobnie z powodu trójkątnego pdf hałasu). Patrząc na dolny koniec, intuicyjne jest zrozumienie, dlaczego sygnał wyjściowy jest rozbieżny: w miarę jak sygnał przerywany zaczyna zawierać wartości ujemne, zaciskanie na wyjściu zmienia wartość dolnych odcinków wyjściowych (tj. Wartości ujemne), tym samym zwiększenie wartości średniej. Ilustracja wydaje się być w porządku (jednolity, symetryczny dither 2LSB, średnia wciąż na żółto):
Teraz, jeśli użyjemy znormalizowanego ditheringu 1LSB, nie będzie żadnych problemów na skrzynkach brzegowych, ale wtedy oczywiście tracimy ładne właściwości trójkątnego ditheringu (patrz np. Ta prezentacja ).
(Pragmatycznym, empirycznym) rozwiązaniem (hack) jest więc powrót do [-0,5; 0,5 [dithering jednolity dla edgecase:
Które naprawia krawędzie przy jednoczesnym zachowaniu nienaruszonego trójkątnego ditheringu dla pozostałego zakresu:
Więc nie odpowiadaj na twoje pytanie: nie wiem, czy istnieje bardziej solidne matematycznie rozwiązanie, i równie chętnie wiem, co zrobili Mistrzowie Przeszłości :) Do tego czasu przynajmniej mamy straszny hack, aby utrzymać funkcjonowanie naszego kodu.
EDYCJA
Prawdopodobnie powinienem uwzględnić sugestię obejścia podaną w pytaniu, dotyczącą po prostu kompresji sygnału. Ponieważ średnia nie jest liniowa w końcowych przypadkach, zwykła kompresja sygnału wejściowego nie daje idealnego wyniku - chociaż naprawia punkty końcowe:
Bibliografia
źródło
dithertri
idithernorm
zamiast niezależnego. Gdy przejdziesz przez całą matematykę i anulujesz wszystkie warunki, przekonasz się, że w ogóle nie trwasz! Zamiast tego kod działa jak twardy punkt odcięciav < 0.5 / depth || v > 1 - 0.5/depth
, natychmiast przełączając się na jednolity rozkład. Nie oznacza to, że odbiera to przyjemne dithering, ale jest to niepotrzebnie skomplikowane. Naprawienie błędu jest w rzeczywistości złe, skończysz gorzej. Po prostu użyj twardego odcięcia.Nie jestem pewien, czy potrafię w pełni odpowiedzieć na twoje pytanie, ale dodam kilka przemyśleń i być może uda nam się wspólnie znaleźć odpowiedź :)
Po pierwsze, podstawa pytania jest dla mnie trochę niejasna: dlaczego uważasz, że pożądana jest czysta czerń / biel, gdy każdy inny kolor ma szum? Idealnym rezultatem po ditheringu jest twój oryginalny sygnał z całkowicie jednolitym szumem. Jeśli czerń i biel są różne, szum staje się zależny od sygnału (co może być w porządku, ponieważ dzieje się tak, gdy kolory są i tak zaciśnięte).
To powiedziawszy, istnieją sytuacje, w których hałas w bieli lub czerni stanowi problem (nie jestem świadomy przypadków użycia, które wymagają, aby zarówno czerń, jak i biel były jednocześnie „czyste”): Podczas renderowania dodatnio mieszanej cząstki jako poczwórnej tekstury, nie chcesz, aby hałas był dodawany w całym kwadracie, ponieważ pojawiłoby się to również poza teksturą. Jednym z rozwiązań jest wyrównanie szumu, a nie dodawanie [-0,5; 1,5 [dodajesz [-2,0; 0,0 [(tj. Odejmuje 2 bity hałasu). To dość empiryczne rozwiązanie, ale nie jestem świadomy bardziej poprawnego podejścia. Myśląc o tym, prawdopodobnie chcesz również wzmocnić swój sygnał, aby zrekompensować utraconą intensywność ...
W pewien sposób Timothy Lottes wygłosił przemówienie GDC na temat kształtowania hałasu w częściach widma, w których jest on najbardziej potrzebny, zmniejszając hałas na jasnym końcu widma: http://32ipi028l5q82yhj72224m8j-wpengine.netdna-ssl.com/wp- content / uploads / 2016/03 / GdcVdrLottes.pdf
źródło
Uprościłem pomysł Mikkel Gjoel dotyczący ditheringu z trójkątnym hałasem do prostej funkcji, która wymaga tylko jednego wywołania RNG. Usunąłem wszystkie niepotrzebne fragmenty, więc to, co się dzieje, powinno być dość czytelne i zrozumiałe:
Dla pomysłu i kontekstu odsyłam cię do odpowiedzi Mikkela Gjoela.
źródło