Czy odroczone renderowanie / cieniowanie jest możliwe w OpenGL ES 2.0?

20

Zapytałem o to na StackOverflow , ale tutaj może to mieć większy sens:

Czy ktoś zaimplementował odroczone renderowanie / cieniowanie w OpenGL ES 2.0? Nie obsługuje MRT, więc przy tylko jednym buforze kolorów nie jest to coś, co można zaimplementować w „zwykły” sposób.

W szczególności odkrywam na iPadzie, iPhonie 4 (może iPhone 3gs) i Androidzie. W aplikacji GLESView na iPadzie / iPhone'ie4 / iPhone3gs rozszerzenie GL_OES_RGB8_RGBA8 jest obecne i jeszcze nie zagłębiłem się zbytnio, ale przy 8 bitach / kanał ten pomysł jest interesujący: http://www.gamedev.net/topic/ 562138-opengl-es-20-and-odroczony-cieniowanie /

Jakieś inne pomysły? Czy warto to robić pod względem wydajności?

Jim Buck
źródło
Tak, to możliwe.
Quazi Irfan
7
Za pomocą jakich technik?
Jim Buck

Odpowiedzi:

15

Tak to mozliwe. Nie jest to jednak szczególnie opłacalne.

Po pierwsze, chyba że masz dostęp do rozszerzenia NV_draw_buffers (jak sama nazwa wskazuje, jest to tylko NVIDIA. Więc jeśli nie korzystasz z Tegra, nie masz go), obiekty bufora ramki w ES 2.0 mogą renderować tylko jeden obraz na czas. Aby wygenerować bufory G, musisz wielokrotnie renderować scenę, co pozbawi jedną z zalet opóźnionego renderowania.

Po drugie, przepustowość na platformach mobilnych nie jest taka sama, jak w przypadku GPU średniej klasy. A przepustowość jest kluczowa dla opłacalnego renderowania odroczonego (dla wielu świateł). Bez tej przepustowości przepuszczanie światła naprawdę będzie boleć, pod względem wydajności.

Po trzecie, sprzęt PowerVR naprawdę nie jest przeznaczony do tego rodzaju rzeczy. Optymalizuje renderowanie dzięki sprzętowi do renderowania opartemu na kafelkach. Odroczone renderowanie dodatkowo byłoby mniej pomocne niż w tradycyjnej architekturze konwersji skanowania.

Nicol Bolas
źródło
6

Głównym problemem jest Fillrate. Na mobilnych GPU współczynnik wypełnienia jest niski, dlatego nie można wykonywać odroczonego cieniowania w czasie rzeczywistym w rozdzielczości natywnej.

Na iPhone 4 i iPad 1 wypełnienie jest po prostu śmieszne. Jedynym urządzeniem IOS z dobrym współczynnikiem wypełnienia jest iPad 2, ale wątpię, aby było wystarczająco ... Na Androidzie tylko urządzenia Tegra mają GL_NV_draw_buffers do korzystania z MRT, ale współczynnik wypełnienia jest również bardzo niski. Mali 400 wydaje się mieć najlepsze wypełnienie. Jeśli chcesz płakać, po prostu spróbuj wypełnić kolorowy prostokąt 4 razy w rozdzielczości pełnoekranowej ... Wiele urządzeń nie może tego zrobić 60 klatek na sekundę.

Na procesorach graficznych dla komputerów stacjonarnych masz 10-krotny (lub więcej) współczynnik wypełnienia jako mobilny gpus. Nie zapominaj, że mobilne procesory graficzne używają tej samej pamięci co procesor i nie masz dedykowanej pamięci.

Istnieje kilka przykładów w WebGL (ten sam API), więc nie jest to ograniczenie API.

Ellis
źródło
1
+1, aby wypełnić słabość. Nie mogłem nawet uzyskać rozmycie Gaussa do uruchomienia na rozdzielczość 1536x2048 przy 60fps (od razu wpadł liczbę klatek na sekundę w dół do 30 klatek na sekundę, nawet tylko 4 próbki)
bobobobo
1
Myślę, że zależy to w dużej mierze od subtelności twojej implementacji i zrozumienia, co wpływa najbardziej na sprzęt mobilny. Na przykład ci faceci wykonali umiarkowanie wydajne rozmycie DoF w 2012 roku.
Inżynier
1

Naprawdę musisz wziąć pod uwagę, jakie jest absolutne minimum potrzebne do odroczenia renderowania. Jeśli cofniesz się do odroczonego oświetlenia, zmniejszy to ilość danych, które muszą być przechowywane w GBuffer, i naprawdę jest to o wiele taniej niż renderowanie połowy sceny 3 lub więcej razy w celu obsługi małej ilości światła.

Wybrałbym następujący format GBuffer:

  • Ponownie użyj bufora głębokości do przejścia oświetlenia, nie wiedząc, jak szeroko jest to obsługiwane na urządzeniach mobilnych, ale jest to tekstura o dowolnej głębokości.
  • Pojedyncza tekstura GBuffera, wewnątrz której bym zapisał: Normalne U, Normalne V, Param 0, Param 1. Kodowanie Lambert-Azimuthal wygląda naprawdę ładnie dla normalnych i kompresuje je w zaledwie dwóch komponentach, stosunkowo niedrogich do kodowania i dekodowania.
  • Dwa parametry zmiennych oświetlenia to dużo, można użyć jednego jako wyliczenia dla wielu funkcji oświetlenia, jeśli sprzęt dobrze radzi sobie z dynamicznym rozgałęzianiem.

Odroczone oświetlenie jest podobne do odroczonego renderowania, z tym że renderujesz scenę dwukrotnie:

  1. Renderuj głębokość geometrii, normalne i parametry oświetlenia do GBuffer.
  2. Renderuj Światła do bufora akumulacji.
  3. Renderuj geometrię za pomocą shaderów materiałów, tutaj również skomponuj swoje oświetlenie. Jeśli potrafisz wypracować odwrotne operatory równań oświetlenia, na tym etapie możesz zrobić wiele naprawdę fajnych rzeczy.
  4. Wykonuj wszelkie dodatkowe przetwarzanie, na jakie Cię stać, pamiętaj, aby nadużyć głębokości i normalnych tekstur na śmierć tutaj ze względu na wydajność.

O przechowywaniu wyników oświetlenia. Przechowuję rozproszone kolory i luminancję, więc bufor akumulacji musi mieć jedynie standardową 32-bitową teksturę koloru. Możesz oszacować kolor zwierciadlany, obliczając kolor rozproszonego koloru i łącząc go z luminancją zwierciadlaną.

Najważniejszą częścią będzie jednak korzystanie z bufora szablonu głębokości w pełni, upewnij się, że nie renderujesz żadnego kodu oświetlenia, który nie jest potrzebny. Posunąłbym się nawet do dodania niektórych instrukcji odrzucania do shaderów fragmentów na warunkach, które obniżą widoczność światła poniżej wyświetlanego zakresu urządzenia (1e-3 jest zwykle bezpiecznym odcięciem).

chronosifter
źródło
discardjest naprawdę zły dla potoków opartych na kafelkach, których używa wiele / większość mobilnych procesorów graficznych.
Inżynier
1

Rozważ odroczenie oświetlenia. W skrócie, odroczone oświetlenie to technika wykorzystująca zredukowaną wersję odroczonego cieniowania do obliczenia jasnej mapy przestrzeni ekranu. W drugim przejściu geometria jest ponownie renderowana przy użyciu mapy świetlnej obszaru ekranu jako informacji o oświetleniu.

Ta technika służy do zmniejszenia wielkości bufora G, ponieważ potrzeba mniej atrybutów. Ma to również tę zaletę, że bufor G i mapa świetlna obszaru ekranu mogą mieć niższą rozdzielczość niż ekran.

Wdrożyłem ścisły renderer oparty na GLES 2.0 (choć eksperymentalny) i udało mi się sprowadzić bufor G do jednej tekstury RGBA (tak, użyłem texture2D zamiast bufora renderowania). Zawierał normalną mapę przestrzeni ekranu + bufor głębokości w kanale alfa (który, o ile pamiętam, został skompresowany za pomocą logarytmu).

Atrybuty pozycji (zwane tutaj światem ) można obliczyć podczas przejścia światła, wykorzystując fakt, że w rzucie perspektywicznym, .xy jest dzielone przez .z , tak że:

xyfarustum=xyworlre/zworlre

Przybliżyłem xy atrybutu pozycji, wykonując:

xyworlre=xyfarustumzworlre

Uwaga: Musiałem dokonać dalszych korekt w zależności od ustawień matrycy projekcyjnej.

Warto również zauważyć, że byłem w stanie pominąć składnik .z wektorów normalnych, ponieważ mogłem zrekonstruować .z z .xy, ponieważ wektor normalny jest znormalizowany, tak że:

x2)+y2)+z2)=1x2)+y2)+z2)=1z2)=1-(x2)+y2))z=1-(x2)+y2))

Korzystając z tej techniki, byłem w stanie zwolnić inny kanał w moim buforze G RGBA i użyłem go do przechowywania mapy zwierciadlanej przestrzeni ekranu (lub połysku, jeśli wolisz).

Simon Schmidt
źródło
BTW: Mój renderer nie był podłączony do żadnego silnika gry. To była wersja demo światowej sławy, oddająca Suzanne.
Simon Schmidt
0

Tak, jest to absolutnie możliwe. Szybkość wypełniania nie stanowi takiego problemu, ponieważ mobilne układy graficzne są zaprojektowane do obsługi ekranów o bardzo wysokiej rozdzielczości. W rzeczywistości pomaga to w odroczonym renderowaniu, ponieważ obliczenia oświetlenia są niezależne od złożoności sceny, więc przerysowanie nie powoduje spowolnienia. Oto moja implementacja na iPadzie czwartej generacji: http://www.youtube.com/watch?v=K4X1oF6b4V8

Jeśli chcesz czterokrotnie zwiększyć wydajność, tylko połowę rozdzielczości renderowanej tekstury. W każdym razie nie widzę nic innego z grafiką 3D na ekranie siatkówki.

Mobilne układy graficzne są wyjątkowo dobre w odroczonym renderowaniu ze względu na sposób, w jaki obsługują renderowanie do tekstury. W przeciwieństwie do kart graficznych na komputery PC, które zwykle powodują ogromne pogorszenie wydajności, gdy zaczyna się renderowanie do tekstury zamiast kontekstu okna, grafika mobilna jest zaprojektowana tak, aby osiągać to bez pogorszenia wydajności. Otrzymujesz więc skalowalność odroczonego renderera bez początkowej utraty wydajności, jakiej doświadczasz na biurkowej karcie graficznej.

W momencie mojej implementacji brakowało renderowania OpenGLES do wielu celów, więc musiałem narysować kolor ekranu i normalne w osobnych przejściach. Można to naprawić w nowszych wersjach OpenGLES, ale nie wiem, czy rozwiązania są jeszcze dostępne w mobilnym sprzęcie konsumenckim.

JoshKlint
źródło
3
„Mobilne układy graficzne są wyjątkowo dobre w odroczonym renderowaniu ze względu na sposób, w jaki obsługują renderowanie do tekstury. W przeciwieństwie do kart graficznych na komputery PC, które zwykle powodują ogromny wzrost wydajności, gdy zaczynasz renderować teksturę zamiast kontekstu okna, grafika mobilna jest zaprojektowane tak, aby osiągać to bez pogorszenia wydajności ”. To ogromne twierdzenie. Czy masz jakieś godne zaufania odniesienia do tego roszczenia?
Panda Pajama