Widzę funkcje ddx
i ddy
glsl i odpowiedniki hlsl pojawiają się w kodzie modułu cieniującego co jakiś czas. Obecnie używam ich do mapowania wypukłości bez stycznej lub bitangentu, ale w zasadzie skopiowałem i wkleiłem kod. Nie rozumiem, czym właściwie są te funkcje, co robią i kiedy chciałbym ich użyć.
Więc pytania:
- Jakie są funkcje pochodne obszaru ekranu?
- Czym zajmują się te funkcje? Wartości wejściowe i wyjściowe
- Do jakich efektów są najczęściej używane?
- Jakie efekty wymagają spojrzenia na te funkcje?
Odpowiedzi:
Po pierwsze, pomaga wiedzieć, że procesory graficzne zawsze oceniają shadery fragmentów / pikseli na 2x2 blokach pikseli jednocześnie. (Nawet jeśli ostatecznie trzeba narysować tylko niektóre z tych pikseli, inne znajdują się poza wielokątem lub są zasłonięte - niepotrzebne fragmenty są maskowane, a nie zapisywane na końcu).
Pochodna przestrzeni ekranowej zmiennej (lub wyrażenia)
v
w twoim module cieniującym jest różnicą wartościv
(w tym punkcie kodu) z jednej strony tego kwadratu 2x2 pikseli na drugą. to znaczy.ddx
jest wartościąv
w prawym pikselu pomniejszoną o wartośćv
w lewym i podobnie dladdy
pionu.To odpowiada „jak szybko
v
rośnie lub maleje, gdy poruszamy się w poziomie (ddx) lub pionowo (ddy) po ekranie?” - tj. w kategoriach rachunku przybliża częściowe pochodne twojej zmiennej (przybliżone, ponieważ wykorzystuje dyskretne próbki na każdym fragmencie, zamiast matematycznie oceniać nieskończenie małe zachowanie funkcji)W przypadku wielkości skalarnych możemy to również postrzegać jako wektor gradientowy,
∇v = float2(ddx(v), ddy(v))
który wskazuje wzdłuż kierunku przestrzeni ekranu, w którymv
rośnie najszybciej.Ten rodzaj informacji jest często wykorzystywany wewnętrznie do wyboru odpowiedniej mipmapy lub anizotropowego jądra filtrującego do wyszukiwania tekstur. Na przykład, jeśli mój aparat wygląda prawie równolegle do pionowego
uv
kierunku teksturowanej płaszczyzny podłogi,ddy(uv.y)
będzie bardzo duży w porównaniu doddx(uv.x)
(ponieważ oś pionowa jest wstępnie skrócona na ekranie - jeden piksel w pionie pokrywa dłuższy odcinek przestrzeni tekstury), co mówi sprzętowi do próbkowania tekstury, że potrzebuję filtrowania anizotropowego, aby rozmazać pionowy kierunek tekstury bardziej niż poziomy, aby uniknąć artefaktów aliasingu.W przypadku najprostszych efektów nie musisz używać tych pochodnych, ponieważ podstawowe metody próbkowania tekstur 2D obsługują je za Ciebie. Ale jak wspomniała Le Comte du Merde-fou w powyższym komentarzu, podczas zniekształcania wyszukiwań tekstur konieczne może być ręczne pobranie i / lub masowanie pochodnych przestrzeni ekranu, aby pomóc sprzętowi wybrać odpowiednie filtrowanie (np. Poprzez
tex2Dlod
w HLSL)Kalkomanie przestrzeni ekranu są jednym z takich przypadków, w których pojedynczy blok 2x2 może pokryć dużą nieciągłość skoku w obliczonej współrzędnej tekstury, co prowadzi do rozmazania lub aliasu krawędzi, jeśli system naiwnie obliczy poziom filtrowania. W tym artykule szczegółowo opisano ten artefakt i przedstawiono sposoby jego złagodzenia .
Te pochodne mogą być również przydatne, gdy używasz funkcji szumu w proceduralnym generowaniu tekstur. Jeśli powiedzmy, że chcesz przekształcić szum proceduralny w normalną mapę, ddx i ddy podają prosty, choć przybliżony sposób, aby obliczyć, jak zmienia się wartość hałasu w pobliżu bieżącego fragmentu i w jaki sposób jest nachylony, więc potrafi skonstruować odpowiednią normalną.
Techniki renderowania wygładzonych linii lub podświetlenia skrzyżowań mogą również wykorzystywać pochodne przestrzeni ekranu, aby zapewnić spójność grubości / opadania i nie zależą od geometrii ani kąta widzenia.
W tym przemówieniu na temat renderowania piasku w Journey mówca wspomniał, że mogliby użyć tych funkcji pochodnych do kontrolowania, jak iskrzący jest piasek wzdłuż zerkających krawędzi ... gdyby o tym wiedzieli (zamiast tego zastosowali sztuczkę mipmapy, które i tak pod maską są zasilane tego rodzaju pochodnymi)
Ostatnia uwaga, o której należy pamiętać: pochodne obszaru ekranu można obliczyć z „grubą” / niską precyzją (co oznacza, że jedna para pochodnych jest wspólna dla całego kwadratu) lub „drobną” / wysoką precyzją (co oznacza, że każdy piksel jest porównywany tylko z jego bezpośrednim sąsiedzi w kwadrze, co może dać cztery odrębne pary pochodnych w kwadracie). Z grubsza jest na ogół dużo, ale jeśli zauważysz, że w efekcie widać 2 x 2 bloki, to dobra wskazówka, którą chcesz przełączyć na dokładność wysoką / wysoką. ;)
(Na schemacie u góry użyłem obliczeń dla drobnych instrumentów pochodnych, ale uważaj, że same ddx / ddy mogą same domyślnie przyjmować grubsze pochodne)
źródło
v
tutaj), a ponieważ jest to quad 2x2, nie ma między nimi żadnych pikseli. Jeśli więc cieniujemy lewy górny fragment kwadratu, a v = 1 tam, a w prawym górnym fragmencie v = 4, to ddx (v) = 3 (mówiąc: „v wzrasta o 3 podczas ruchu od lewej do prawej ”)