Planuję wykonać instancję geometrii w OpenGL ES 2.0 Zasadniczo planuję renderować tę samą geometrię (krzesło) może 1000 razy w mojej scenie.
Jak najlepiej to zrobić w OpenGL ES 2.0?
Rozważam przekazanie widoku modelu mat4 jako atrybutu. Ponieważ atrybuty są dla danych wierzchołków, muszę przekazać tę samą matę4, trzy razy dla każdego wierzchołka tego samego trójkąta (ponieważ widok modelu pozostaje stały w poprzek wierzchołków trójkąta).
Oznaczałoby to wiele dodatkowych danych wysłanych do GPU (2 dodatkowe wierzchołki * 16 liczb zmiennoprzecinkowych * (liczba trójkątów) ilość dodatkowych danych).
A może powinienem wysyłać mat4 tylko raz na trójkąt? Ale jak to możliwe, używając atrybutów, skoro atrybuty są zdefiniowane jako dane „na wierzchołek”?
Jaki jest najlepszy i najskuteczniejszy sposób wykonywania instancji w OpenGL ES 2.0?
źródło
glVertexAttribDivisor
:(Odpowiedzi:
ES2 nie ma glVertexAttribDivisor ani tekstur zmiennoprzecinkowych, więc twoje opcje są dość ograniczone.
Zdecydowanie umieść swój model krzesła w VBO, jeśli jeszcze tego nie robisz. Stamtąd jesteś mniej lub bardziej ograniczony do indywidualnych losowań - po jednym na krzesło - więc kwestia uzyskania macierzy transformacji dla każdego krzesła do GPU jest tak wydajna, jak to możliwe.
Możesz to zrobić za pomocą zwykłych wywołań glUniform, lub możesz nadużyć niektórych dodatkowych gniazd atrybutów wierzchołków i wykonać niektóre wywołania glVertexAttrib (uwaga: nie glVertexAttribPointer) przed narysowaniem każdego krzesła, określając macierz za pomocą 4 takich gniazd, a te wartości będą „trzymać się” dla każdy kolejny wierzchołek krzesła. To może być wystarczająco szybka ścieżka na niektórych urządzeniach, ale wolniejsza na innych, więc będziesz musiał eksperymentować.
Jeśli twoje krzesła nie obracają się jeszcze jedną rzeczą, którą możesz zrobić, to po prostu przesłać pozycję do shadera i zbudować nową macierz transformacji w locie. To brzmi okropnie, ale w rzeczywistości jest niesamowicie szybkie (po prostu ustawia 3 zmiennoprzecinkowe) i może wykonać zadanie.
Ogólnie biorąc i zakładając, że dążysz do typowej platformy mobilnej, myślę, że cokolwiek zrobisz, połączenia losowe cię zabiją.
źródło
Najlepszym rozwiązaniem jest zastosowanie instancji podobnej do skórowanych modeli. Utwórz VBO, które pomieści wiele kopii twojego krzesła, wszystkie identyczne. Teraz każdy wierzchołek musi mieć atrybut bajtowy, który będzie przechowywał indeks do macierzy transformacji, do której zostanie zastosowany. Wyślij tablicę macierzy do shadera i wykorzystaj je jako światową transformację każdego z krzeseł. W ten sposób możesz pobrać w każdym wywołaniu tyle krzeseł, ile maksymalny rozmiar parametru tablicy, bez konieczności przepisywania jakichkolwiek danych w VBO.
źródło
Wolfire Games ma doskonały wpis na blogu o szybkim tworzeniu obiektów . To, co robią, to renderowanie modelu kilka razy, ale wysyłanie innej macierzy dla każdego obiektu do jednolitego gniazda.
Jest to dość skuteczny sposób na umieszczenie całej gamy obiektów, ponieważ wystarczy wysłać dane tylko raz (największym wąskim gardłem przy renderowaniu partii obiektów będzie zawsze przepustowość), a następnie przekształcić model w moduł cieniujący.
źródło
http://www.youtube.com/watch?v=rfQ8rKGTVlg
To jest Google Talk na WebGL, czyli OpenGL ES dla JavaScript, co oznacza, że nie ma również wystąpienia geometrii. To może dać ci pomysł, choć trudno powiedzieć, ponieważ nie wiem, czy twoje wąskie gardło dotyczy GPU, czy procesora.
Chociaż powinieneś dowiedzieć się o zmiennych jednolitych, absolutnie nie ma potrzeby wysyłania mat4 w atrybucie, wszystkie wierzchołki twojego krzesła zostaną przekształcone przez tę samą macierz, musisz wysłać tylko raz na model, a nie na trójkąt. Umożliwiają to jednolite zmienne, są to specjalne zmienne, które można ustawić w samym programie cieniującym.
źródło