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?
android
ios
opengl-es2
Jim Buck
źródło
źródło
Odpowiedzi:
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.
źródło
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.
źródło
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:
Odroczone oświetlenie jest podobne do odroczonego renderowania, z tym że renderujesz scenę dwukrotnie:
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).
źródło
discard
jest naprawdę zły dla potoków opartych na kafelkach, których używa wiele / większość mobilnych procesorów graficznych.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:
Przybliżyłem xy atrybutu pozycji, wykonując:
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:
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).
źródło
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.
źródło