Jaki jest kompromis między renderowaniem w przód a odroczonym?

9

Renderowanie w przód jest procesem obliczania wartości promieniowania dla fragmentu powierzchni bezpośrednio z geometrii wejściowej i informacji o oświetleniu. Odroczone renderowanie dzieli ten proces na dwa etapy: najpierw tworzy bufor przestrzeni ekranowej zawierający właściwości materiału (bufor geometrii lub bufor G) zbudowany przez rasteryzację geometrii wejściowej, a drugi tworzy wartość promienia dla każdego piksela przez połączenie G- bufor z informacjami o oświetleniu.

Odroczone renderowanie jest często przedstawiane jako optymalizacja renderowania do przodu. Jednym z wyjaśnień jest to, że oświetlenie jest dość drogie, a jeśli masz jakiś overdraw, to oświetlasz piksele, które nigdy nie będą widoczne na ekranie, podczas gdy jeśli przechowujesz właściwości materiału w buforze G, a następnie światło, to oświetlasz tylko piksel, który będzie faktycznie pojawiają się na ekranie. Czy jest to faktycznie zaleta odroczenia, biorąc pod uwagę, że można również wykonać wstępne przejście do głębokości, a następnie wykonać przejście do renderowania do przodu z testem głębokości ustawionym na D3D11_COMPARISON_EQUALlub GL_EQUALrównoważnym?

Odroczone renderowanie ma również potencjał lepszego planowania na GPU. Rozdzielenie jednego dużego frontu osnowy / fali na falę o mniejszej geometrii, a następnie mniejsze fronty świetlne później poprawia zajętość (więcej frontu fal w locie jednocześnie). Ale kończy się to również na znacznie większym wykorzystaniu przepustowości (zapisywanie dużej liczby kanałów do bufora G, a następnie odczytywanie ich z powrotem podczas oświetlenia). Oczywiście szczegóły tutaj zależą w dużej mierze od twojego procesora graficznego, ale jakie są ogólne zasady?

Czy istnieją inne praktyczne rozważania dotyczące wydajności przy podejmowaniu decyzji o renderowaniu do przodu i odroczonym? (Załóżmy, że w razie potrzeby możemy użyć wariantów każdej techniki: tzn. Możemy również porównać kafelki do przodu z kafelkami odroczonymi).

John Calsbeek
źródło

Odpowiedzi:

11

Można uniknąć nadpisywania nieprzezroczystych obiektów nawet przy renderowaniu do przodu, wykonując wstępne przejście głębokości i wykorzystując te informacje, aby odrzucić piksel, który nie jest tak naprawdę widoczny. Jednak, w zależności od kosztu wierzchołka sceny, wstępne przejście na głębokość może dodać niedopuszczalną ilość narzutu wydajności. Ponadto renderowanie przy użyciu potoku cieniowania pikseli procesora graficznego oznacza, że ​​nie płacisz kosztu za renderowany piksel, płacisz za renderowany kwadrat 2x2 pikseli . Zatem nawet wykonanie wstępnego przejścia na głębokość nadal powoduje marnowanie krawędzi trójkąta przez piksele cieniowania, które zostaną odrzucone.

Planowanie układów GPU jest złożonym tematem, a kompromis między przekazywaniem do przodu i odroczeniem nie sprowadza się po prostu do „działania szybciej, ale zużywania większej przepustowości”. Jeśli masz dwie równie tanie operacje, które działają sekwencyjnie i każda z nich korzysta z tej samej liczby zasobów, nie ma powodu, aby dzielić je na osobne moduły cieniujące: dwie małe fronty falowe, z których każda korzysta z zasobów X, nie działają zasadniczo lepiej niż jedna dłuższa frontu falowego, który używa również zasobów X. Jeśli masz tanią operację i kosztowną operację do uruchomienia w sekwencji, może skorzystać z podziału na osobne moduły cieniujące: moduł cieniujący ogólnie zarezerwuje maksymalną ilość zasobów, które może wykorzystać w dowolnym momencie. To' Można sobie wyobrazić, że renderowanie w przód może nie być w stanie wykorzystać całej przepustowości twojego GPU, ponieważ w locie jest tak mało frontów falowych, że nie jest w stanie wykonać wystarczającej liczby operacji do nasycenia przepustowości. Ale jeśli ty ograniczone przepustowość, odroczone renderowanie może nie przynosić korzyści (ponieważ prawdopodobnie wykorzysta większą przepustowość).

Dodatkowym problemem związanym z wydajnością jest to, że renderowanie w przód obsługuje różne typy materiałów (powiedzmy różne BRDF) po prostu za pomocą innego modułu cieniującego dla tego obiektu. Prosty, odroczony renderer musi obsługiwać różne typy materiałów w inny sposób (potencjalnie gałąź w module cieniującym), ponieważ praca nie jest już pogrupowana w osnowy / fronty spójnie w zależności od renderowanego obiektu. Można to złagodzić za pomocą renderera kafelkowego - jeśli tylko określone obszary ekranu używają alternatywnego rodzaju materiału (powiedzmy, do włosów), możesz użyć wariantu modułu cieniującego z gałęzią typu materiału tylko dla płytek zawierających dowolne piksele z tego materiału .

John Calsbeek
źródło