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.
- 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?)
- Czy można przynajmniej przyspieszyć te poszukiwania, wykorzystując w jakiś sposób lokalizację pikseli, z którymi można pracować?
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"
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."
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:
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.
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