Odroczone cieniowanie to tylko technika „odroczenia” faktycznej operacji cieniowania na późniejszych etapach. Może to być świetne, aby zmniejszyć liczbę wymaganych przejść (na przykład), aby uzyskać 10 świateł, które wymagają 10 przejść. Chodzi mi o to, że niezależnie od używanej techniki renderowania istnieją pewne możliwe optymalizacje renderowania, które zmniejszają liczbę obiektów (wierzchołków, normalnych itp.), Które musi przetworzyć Twój potok renderowania.
Nie ma de facto standardu dla optymalizacji renderowania, a raczej szereg technik, które można stosować zamiennie lub łącznie, aby osiągnąć określone parametry wydajności. Korzystanie z każdej techniki w dużej mierze zależy od charakteru renderowanej sceny.
Odroczone renderowanie próbuje rozwiązać problem, gdy rośnie liczba świateł, co w renderowaniu do przodu może spowodować eksplozję liczby przejść.
Techniki te nie optymalizują bezpośrednio odroczonej części cieniującej, ale zgodnie z twoim opisem, odroczona część cieniująca NIE jest twoim problemem. Problem polega jednak na tym, że poddajesz całą scenę procesowi renderowania. Zatem silnik musi przetworzyć (na przykład wszystkie 100 milionów wierzchołków) w scenie, aby móc przesłać wynik do bufora g, podczas gdy większość z tych 100 milionów wierzchołków można w prosty sposób utajnić i nie przesłać do wierzchołek i fragmenty wstępnego przetwarzania przechodzą.
W przypadku mechanizmu renderującego w przód N wierzchołek będzie przetwarzany przez etap wierzchołka jako całość, vertex count*lights count
a przez etap fragmentu jako całość fragments count*number Lights
, odroczone cieniowanie skutecznie zmniejsza to tylko vertex count
do etapu wierzchołka i fragments count
liczby fragmentów, przed rozwiązaniem rzeczywiste zacienienie. Nadal jednak N może być zbyt trudne do przetworzenia, zwłaszcza gdy większość z nich może zostać trywialnie wyrzucona.
Dzięki temu wygładzanie jest bardziej skuteczne w przypadku renderowania do przodu / wielokrotnych przejść. Należy jednak pamiętać, że większość silników korzysta z metody podwójnego renderowania, ponieważ samo odroczone cieniowanie nie jest w stanie rozwiązać przezroczystych obiektów , dlatego stosowanie tych optymalizacji jest koniecznością, nie znam żadnego komercyjnego silnika, który nie zrobiłby wszystkich z nich.
Custing Frustum
Tylko obiekty, które są całkowicie lub częściowo uwzględnione w widoku widoku, zawsze muszą być przesyłane do potoku renderowania. Jest to podstawowa koncepcja ubijania frustum, niestety sprawdzanie, czy siatka znajduje się w polu widzenia, czy frustum, może być kosztowną operacją, dlatego projektanci silników używają przybliżonej objętości granicznej, takiej jak obwiednia wyrównana do osi (AABB) lub kula ograniczająca , chociaż może to nie być tak dokładne jak użycie rzeczywistej siatki, różnica dokładności nie jest warta sprawdzenia z rzeczywistą siatką.
Nawet w przypadku woluminów ograniczających nie trzeba tak naprawdę sprawdzać każdego z nich, alternatywnie można zbudować hierarchię woluminów ograniczających, aby wykonać wcześniejsze ubijanie, przy czym jest to wysoce zależne od złożoności sceny.
Jest to dobra i prosta technika dla mniejszego silnika i jest prawie stosowana w każdym silniku, z którego kiedykolwiek korzystałem. Zalecam stosowanie „normalnego” sprawdzania objętości granicznej / frustracji bez hierarchii, jeśli silnik nie wymaga renderowania bardzo złożonych scen.
Odwrotna twarz
To konieczność, po co rysować twarze, które i tak nie będą widoczne? Renderowanie interfejsów API zapewnia interfejs do włączania / wyłączania wygładzania tylnej ściany. Jeśli nie masz silnego powodu, aby go nie włączyć, jak niektóre aplikacje CAD, które w pewnych okolicznościach muszą rysować backface'y, jest to konieczne.
Ubijanie okluzji
Za pomocą bufora Z można rozwiązać określenie widoczności. Problem polega jednak na tym, że bufor Z nie zawsze jest świetny pod względem wydajności, ponieważ bufor Z można rozwiązać tylko na późniejszych etapach potoku, obiekty zasłaniane powinny zostać zrasteryzowane i mogą zostać zapisane w buforze Z i Bufor kolorów przed nieudanym testem Z.
Wyrównanie okluzji rozwiązuje ten problem, wykonując kilka wczesnych testów w celu wycięcia obiektów okluzji znajdujących się w obszarze renderowania. Jedną praktyczną implementacją usuwania okluzji jest stosowanie zapytań punktowych i sprawdzanie, czy niektóre obiekty są widoczne z określonego punktu widzenia. Można to również wykorzystać do wygaszania świateł, które nie przyczyniają się do uzyskania ostatecznego obrazu, co jest szczególnie przydatne w odroczonym renderowaniu silnika.
Doskonałym przykładem takiej techniki jest GTA5, w której drapacze chmur są umieszczone strategicznie w centrum miasta, są nie tylko dekoracjami, ale także działają jako okludery, skutecznie zasłaniając resztę miasta i zapobiegając jego byciu zrasteryzowany.
Poziom detali
Poziom szczegółowości jest szeroko stosowaną techniką, ideą jest użycie prostszej wersji siatki, gdy siatka w mniejszym stopniu przyczynia się do sceny. istnieją dwie wspólne implementacje; jeden po prostu zamienia siatkę na prostszą, gdy nie ma już większego wpływu, siatka jest wybierana na podstawie jakiegoś czynnika, takiego jak odległość i liczba pikseli (obszar na ekranie), które zajmuje siatka. Druga wersja dynamicznie tesseluje siatkę, która jest szeroko stosowana w renderowaniu terenu.
Co jeśli wszystkie te nie zadziałały?
To dobre pytanie.
Pierwszą rzeczą, którą musisz zrobić, jest profilowanie aplikacji za pomocą profilera graficznego i określenie, gdzie jest wąskie gardło. Należy pamiętać, że wąskie gardło może ulec zmianie wraz ze zmianą renderowanej treści. Wąskie gardła mogą być również częścią kodu działającego na procesorze, więc również musisz to zmierzyć.
Następnie musisz dokonać optymalizacji na wąskim gardle, pamiętaj, że nie ma na to właściwej odpowiedzi i będzie się różnić od sprzętu do drugiego.
Niektóre popularne sztuczki optymalizacji GPU:
- Unikaj rozgałęzień w shaderach.
- Wypróbuj różne struktury wierzchołków, na przykład
{VNT}
przeplatane w tej samej tablicy lub {V},{N},{T}
w różnych tablicach.
- Narysuj scenę od przodu do tyłu.
- Wyłącz bufor Z w niektórych punktach, na przykład jeśli obraz nie wymaga testowania Z.
- Użyj skompresowanych tekstur.
Niektóre typowe triki optymalizacji procesora:
- Użyj funkcji wbudowanych dla małych funkcji.
- Jeśli to możliwe, użyj SIMD (wiele danych pojedynczej instrukcji).
- Unikaj buforowania nieprzyjaznych skoków pamięci.
- Używaj VBO z „odpowiednią” ilością danych. (w zależności od sprzętu), ale zwykle im mniej połączeń losowych, tym lepiej.
Ale co, jeśli moje wąskie gardło było w odroczonym cieniowaniu?
W tym przypadku, ponieważ odroczone cieniowanie bardziej dotyczy świateł, najbardziej oczywistą częścią jest optymalizacja faktycznych obliczeń zacienienia. niektóre z punktów, na które należy uważać:
- Renderuj światła, które faktycznie wpływają na ostateczny obraz. Innymi słowy, wyłącz światła, które nie przyczyniają się. Można to skutecznie wdrożyć za pomocą funkcji usuwania okluzji, o której wspomniałem wcześniej.
- Czy to światło potrzebuje odbłyśnika lub innych składników? Może nie.
- Czy to światło rzuca cień? Niektóre światła nie muszą rzucać cieni.
- Czy ten lekki udział można wstępnie obliczyć? Jeśli się nie porusza, prawdopodobnie pewne aspekty można wstępnie obliczyć.
Twój problem nie jest związany z odroczonym cieniowaniem , musisz zaimplementować podstawowe podstawowe elementy renderera, zanim spróbujesz przyspieszyć określoną część.
Kiedy skończysz z tym, co wyjaśnił concept3d, jeśli rzeczywiście okaże się, że musisz zoptymalizować sam odroczony moduł cieniujący (w przeciwieństwie do całego przejścia rasteryzacji), możesz zaimplementować odroczone cieniowanie oparte na kafelkach.
Jeśli nie jesteś ograniczony liczbą dynamicznych świateł, powinieneś rozważyć, dlaczego w ogóle używasz odroczonego cieniowania, ale jeśli tak, to spróbuj wypróbować optymalizację, która umożliwiła Battlefield 3. (Wskazują na to w slajdzie 10 swojego publicznego pliku PDF: http://dice.se/wp-content/uploads/GDC11_DX11inBF3_Public.pdf )
źródło