Jaki jest najskuteczniejszy sposób na zaimplementowanie filtra splotowego w pixel shader?

Implementacja splotu w pixel shader jest dość kosztowna ze względu na bardzo dużą liczbę pobieranych tekstur.

Bezpośrednim sposobem implementacji filtra splotowego jest wykonanie N X N wyszukiwania na fragment przy użyciu dwóch cykli na fragment. Proste obliczenia mówią, że obraz 1024x1024 rozmyty z jądrem Gaussa 4x4 wymagałby 1024 x 1024 x 4 x 4 = 16M wyszukiwania.

Co można z tym zrobić?
  1. czy można użyć jakiejś optymalizacji, która wymagałaby mniej poszukiwań? Nie jestem. interesują Cię optymalizacje specyficzne dla jądra, takie jak te dla Gaussa (czy są specyficzne dla jądra?)
  2. Czy można przynajmniej przyspieszyć te poszukiwania, wykorzystując w jakiś sposób lokalizację pikseli, z którymi można pracować?
Dzięki!
Author: Albus Dumbledore, 2011-03-09

3 answers

Jądra Gaussa są rozdzielne, co oznacza, że możesz najpierw przejść poziomo, potem pionowo (lub odwrotnie). To zamienia O (N^2) W O (2N). To działa dla wszystkich filtrów rozdzielnych, nie tylko dla rozmycia(nie wszystkie filtry są rozdzielne, ale wiele z nich jest, a niektóre są"tak dobre jak").

Lub, w konkretnym przypadku filtra rozmycia (Gaussa lub Nie), które są wszelkiego rodzaju "sumami ważonymi", można skorzystać z interpolacji tekstur, która może być szybsza dla małych wielkości jądra (ale ostatecznie nie dla dużych rozmiarów jądra).

EDIT: obrazek do metody "interpolacja liniowa"

"Metoda interpolacji liniowej"

Edytuj (zgodnie z życzeniem Jerry ' ego Coffina), aby podsumować Komentarze:

W metodzie" texture filter " interpolacja liniowa wytworzy ważoną sumę sąsiednich teksteli zgodnie z odwrotną odległością od lokalizacji próbki do środka teksteli. Odbywa się to za pomocą sprzętu teksturującego, za darmo. W ten sposób 16 pikseli można podsumować w 4 / align = "left" / Filtrowanie tekstur może być wykorzystywane oprócz oddzielania jądra.

Na przykładowym obrazku, w lewym górnym rogu, próbka (okrąg) trafia w środek tekstu. To co dostajesz jest takie samo jak filtrowanie" najbliższe", dostajesz wartość tego texela. W prawym górnym rogu, jesteś w środku między dwoma tekstelami, co masz jest średnia 50/50 między nimi (na zdjęciu przez jaśniejszy shader niebieski). W prawym dolnym rogu próbkujesz pomiędzy 4 teksturami, ale nieco bliżej góry w lewo. To daje średnią ważoną wszystkich 4, ale z wagą tendencyjną w kierunku lewego górnego rogu (najciemniejszy odcień niebieskiego).

Poniższe propozycje są dzięki uprzejmości datenwolf (patrz poniżej):

"inną metodą, którą chciałbym zasugerować, jest działanie w przestrzeni Fouriera, gdzie splot zamienia się w prosty produkt przekształconego sygnału Fouriera i przekształconego jądra Fouriera. Chociaż transformata Fouriera na samym GPU jest dość żmudna do wdrożenia, przynajmniej przy użyciu Shadery OpenGL. Ale jest to dość łatwe zrobić w OpenCL. Właściwie to realizuję takie rzeczy używając OpenCL, teraz dużo przetwarzania obrazu w moim silniku 3D dzieje się w OpenCL.

OpenCL został specjalnie zaprojektowany do pracy na GPU. Szybka transformata Fouriera jest fragmentem przykładowego kodu w artykule OpenCL Wikipedii: en.wikipedia.org/wiki/OpenCL i tak przyrost wydajności jest ogromny. FFT wykonuje się z co najwyżej O (n log n), odwrotnie to samo. Jądro filtra Fouriera reprezentacja może być wstępnie obliczona. Sposobem jest FFT - > mnożenie przez kernel - > IFFT, co sprowadza się do operacji O(n + 2N log n). Zwróć uwagę, że rzeczywista splot jest tylko O (n) tam.

W przypadku rozdzielnej, skończonej splotu, jak Rozmycie Gaussa, rozwiązanie separacji przewyższy metodę Fouriera. Jednak w przypadku uogólnionych, możliwych nierozdzielnych jąder metody Fouriera są prawdopodobnie najszybszą dostępną metodą. OpenCL ładnie integruje się z OpenGL, np. można użyj buforów OpenGL (tekstur i wierzchołków) zarówno dla wejścia, jak i wyjścia programów OpenCL."

 18
Author: Damon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-09 19:34:03

Więcej niż jest rozdzielne, filtry Gaussa są również obliczalne W O(1):

Istnieją rekurencyjne obliczenia, takie jak deriche:

Http://hal.inria.fr/docs/00/07/47/78/PDF/RR-1893.pdf

 4
Author: fa.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-09 11:02:02

Odpowiedź Rotoglupa na moje pytanie tutaj warto przeczytać; w szczególności ten wpis na blogu o rozmyciu Gaussa naprawdę pomógł mi zrozumieć pojęcie filtrów separacyjnych.

 3
Author: Nicolas Lefebvre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:31:35