Co jest bardziej wydajne w renderowaniu wokseli: gotowe VBO lub moduł do cieniowania geometrii?

26

Biorąc pod uwagę dość statyczną macierz wokseli, co jest bardziej wydajne: użycie procesora do wstępnego wygenerowania VBO do renderowania ścian wokseli (na razie ignorowanie bardziej zaawansowanych form renderowania, takich jak marszowe kostki) lub użycie modułu cieniującego geometrię na GPU do wygenerowania twarze w locie?

Nie martwię się o aktualizację zmieniających się wokseli, ale oczywiście jest to zaleta wersji GPU, ponieważ nie trzeba odbudowywać VBO. Ponadto podejście GS wydaje się nieco bardziej nowoczesne :)

Z drugiej strony nie przyjrzałem się szczegółom, w jaki sposób GS współpracuje z potokiem rasteryzacji we współczesnych procesorach graficznych. Czy wyprowadza wierzchołki do pewnego rodzaju bufora strumieniowego, czy też wierzchołki są zapisywane w normalnej pamięci GPU pomiędzy nimi? Jeśli to drugie, generowanie w locie może zmniejszyć dostępną przepustowość i moc obliczeniową z pozostałych zadań GPU, a sądzę, że bardziej korzystne byłoby to zrobić na CPU.

Bjorn Wesen
źródło

Odpowiedzi:

9

Mam na myśli scenę typu Minecraft, w której woksel oznacza świat bloków, które są renderowane za pomocą wielokątów:

Jeśli użyjesz modułu cieniującego geometrię, trudno będzie uniknąć posiadania dokładnie trzech ścian (lub cokolwiek innego) na woksel.

Jeśli masz wiele sąsiadujących bloków, które mają tę samą teksturę, możesz użyć kafelkowania tekstur, aby mieć znacznie mniej trójkątów w swoim (zdegenerowanym) pasku w podejściu VBO. Mam na myśli, że jeśli jest ładny duży płaski obszar wokseli trawy 6x6, możesz narysować całą górę w zaledwie 2 trójkątach zamiast 64.

Dzięki podejściu GS nie można wykonać trywialnego usuwania twarzy zasłoniętego przez sąsiadujące woksele, co jest bardzo proste w przypadku podejścia VBO.

Nie próbowałem podejścia GS, ale mogę powiedzieć, że podejście VBO z łączeniem powtarzających się sąsiadujących płytek działa bardzo dobrze. Odkryłem, że bałagan w indeksach elementów jest znacznie wolniejszy niż tylko powtarzanie wierzchołków. Jeśli podzielisz swój świat na ładne małe kostki, zwykle możesz użyć tylko jednego bajtu na komponent na wierzchołek, a nawet spakować informacje o teksturze i normalne (powierzchnia na sześcianie wyrównanym do osi ma tylko 3 możliwe normalne) itp. 4 bajty na wierzchołek, co jest ładne i szybkie.

Użyłem osobnych VBO dla każdej z 6 twarzy - zawsze musisz tylko narysować najwyżej 3 z nich. Pasuje to ładnie z różnymi teksturami zwykle używanymi w górnej części wokseli w stylu Minecraft. Ponieważ dla każdego zestawu normalna i taka jest wówczas jednolita.

Za pomocą pionowych kafelków pixmap w atlasie z GL_REPEATosią poziomą i mając obrócone o 90 stopni wersje pixmap w tym samym atlasie odkryłem, że mogę narysować ogromne ilości pozornie różnych bloków przy użyciu tego samego VBO w tym samym wywołaniu. W przykładzie z trawą 6x6 podzieliłbym to na 12 trójkątów, ponieważ powtarzam tylko jeden wymiar w moim atlasie.

Pracowałem głównie na bardzo niskim poziomie zintegrowanych układów graficznych i urządzeń mobilnych, gdzie GS jest czymś, o czym mogę marzyć o jednym dniu gry.

Wola
źródło
3
Musisz narysować maksymalnie 3 twarze na woksel, ale może być konieczne narysowanie różnych twarzy dla każdego woksela, w zależności od punktu widzenia, więc optymalizacja nie jest tak łatwa, prawda? Wstępnie wykonane VBO będzie zawierać więcej niż jeden woksel. Jeśli twój punkt widzenia znajduje się pomiędzy wokselami, zobaczysz wschodnią stronę jednej i zachodnią stronę drugiej. Jedynym sposobem, w jaki to pomogłoby, jest to, że możesz w prosty sposób wykorzenić rzeczywiste twarze tyłem do kierunku jazdy, ale najgorszym przypadkiem jest nadal renderowanie 5 z 6 stron w grupie wokseli. Jeśli twój punkt widzenia znajduje się poza osiowymi granicami VBO, musisz tylko renderować 3 strony.
Bjorn Wesen,
Spot na Bjorn, jego wykonalność. (Ale w razie potrzeby tworzę VBO dla bloków i ponownie zastanawiam się nad tym, co zbudowałem, gdy kamera się porusza, zamiast mieć cały świat w VBO, więc mam naturalny czas na dokonanie tych wyborów)
Czy
10

Co z trzecią opcją, używając tablic instancji? Zasadniczo rysujesz wiele pudełek (wykonanych z prostej 8-wierzchołkowej kostki) za pomocą pojedynczego wywołania losowania, pozyskując pozycje (i inne dane) jako atrybuty dla poszczególnych instancji z voxel-data VBO (używając glVertexAttribDivisorOpenGL, jestem pewien DX też to ma). Może to być szybsze niż podejście do modułu cieniującego geometrię, chociaż kod aplikacji (inny niż moduł cieniujący) powinien być dość podobny, ponieważ pamiętam, że moduły cieniujące geometrię mają reputację powolnego działania, chociaż nie mam z nimi doświadczenia (lub instancji), gdy wciąż siedzę na sprzęcie 2.1.

Ale w każdym razie albo shadery geometrii, albo tablice instancji powinny być bardziej odpowiednie niż geometria wokseli zbudowana z procesora, szczególnie gdy dane wokseli mogą ulec zmianie. W połączeniu ze sprzężeniem zwrotnym z transformacji (wyjście strumienia w DX?) Możesz być w stanie ustawić dobrą technikę cullingu opartą na GPU.

Chris mówi Przywróć Monikę
źródło
Tak, to najlepsze rozwiązanie tego problemu. Dlaczego mi się nie przydarzyło? :)
Notabene
Po kilku eksperymentach muszę powiedzieć, że wypalona geometria bije każdą instancję z szerokim marginesem. Jednak nie próbowałem jeszcze shaderów geometrii.
Jari Komppa,
@JariKomppa, czy możesz wyjaśnić, co masz na myśli mówiąc o wypalonej geometrii?
Steven Lu,
Instancje wstępnie przetłumaczone i skopiowane do pojedynczej siatki. Jak posiadanie jednej siatki reprezentującej sto kostek lub cokolwiek innego.
Jari Komppa,
@JariKomppa Widziałem te same wyniki, w których tworzenie siatki jest znacznie szybsze. Jednak w GTX 680 opcja instancji wydaje się działać znacznie szybciej, dziwnie.
Levi H
1

Wersja modułu cieniującego geometrię brzmi dla mnie znacznie lepiej. Możesz mieć tylko point vbo i konstruować pole w locie (punkt wejściowy, wyjściowy strumień trójkątów). Będzie szybki (nawet szybszy, jeśli użyjesz jednostki teselacji w modelu shadera 5 równ. DX11) i bardzo zmniejszy przepustowość, będzie to miłe i czyste rozwiązanie.

O GS. Jest umieszczany między modułem cieniującym wierzchołki i modułem cieniującym piksele i modyfikuje wyjściowy strumień wierzchołków (prymitywów). Podczas gdy moduł cieniujący wierzchołek działa tylko na wierzchołkach, moduł cieniujący geometrię działa na całych operacjach podstawowych. Wyjście tego strumienia trafia tylko do modułu cieniującego piksele (i jest wcześniej zrasteryzowany :)) i nie ma sposobu, aby go zapisać. (Może przez jakieś szalone renderowanie tekstury, a następnie parsowanie go ... ale nie ma naprawdę prostej możliwości)

Uwaga dotycząca wydajności: Powinieneś być w stanie przejść do wszystkiego w module cieniującym geometrię i pominąć (wystarczy przekazać dane) moduł cieniujący wierzchołek. Ale to nie najlepszy sposób. Lepiej (szybciej) jest wykonać większość możliwej transformacji w module cieniującym wierzchołki i spróbować zminimalizować program modułu do cieniowania geometrii. Nie obawiaj się korzystać z cyklu, jeśli będziesz go potrzebować (na przykład do tworzenia skrzynek). Kompilator rozwinie go dla Ciebie.

Notabene
źródło
2
Dobrym pomysłem może być sprawdzenie sąsiadujących wokseli w module geometrii i / lub cieniowaniu wierzchołków i odrzucenie wierzchołków lub pominięcie twarzy, jeśli są one zasłonięte. W przeciwnym razie rozwiązanie GS zwiększy używane pasmo.
Tamschi,
Bandwith nie będzie dużym problemem (z moich doświadczeń), ale oczywiście jest to prawda. I nie możesz wyszukiwać w innych prymitywach w GS (czy wiem :)).
Notabene,
@Tamschi: tak, ten problem wystąpił mi zaraz po napisaniu tego pytania .. w przypadku wersji procesora woksele w środku ciał stałych są tłumione, ale może to być niemożliwe na GPU bez wstępnego przejścia z czymś, co stanowiłoby różnicowanie ..
Bjorn Wesen
1
Możesz powiązać bufor wierzchołków z mundurem isamplerBuffer lub usamplerBuffer w module cieniującym, a następnie wykonać wyszukiwania z teksturą (nazwa_jednostki, indeks). Inną opcją byłoby powiązanie bufora z jednolitą tablicą, co daje większą swobodę w wyborze formatu wierzchołków.
Tamschi,