Czy to nie dokładnie to, co robił OpenGL bez modułu cieniującego geometrię?
Nie, nie jest. GS jest krokiem opcjonalnym , a nie krokiem domyślnym.
Aby OpenGL mógł wykonać moduł cieniujący geometrię , musi wykonać tak zwane „ prymitywne złożenie ”. Kiedy renderujesz serię trójkątów za pomocą GL_TRIANGLE_STRIP
, OpenGL zrobi rzeczy wewnętrzne, aby przekształcić każde 3 sąsiadujące wierzchołki w pojedynczy trójkąt, odpowiednio modyfikując kolejność uzwojenia.
Zwykle, gdy nie używa się GS, proces ten jest wykonywany raz. Jeśli jednak używasz GS, musisz je wykonać przed GS. Ale należy to również wykonać po GS, ponieważ GS może generować zupełnie inny typ pierwotny (np. Quady).
Więc teraz sprawiasz, że system w zasadzie wykonuje wiele dodatkowej pracy za darmo. W końcu OpenGL nie może zakładać, że twój GS nic nie robi (to nierozstrzygalny problem).
Ponadto wiele optymalizacji nie działa już w obecności GS. Rozważ renderowanie indeksowane.
Każdy indeks z bufora tablicy elementów wygeneruje te same dane wyjściowe z modułu cieniującego wierzchołki. Więc GPU często buforować tych wyjść w pamięci podręcznej po T & L . Jeśli zobaczy indeks, który jest już w pamięci podręcznej, VS nie zostanie ponownie uruchomiony; po prostu pobiera dane z pamięci podręcznej.
Co to jest"? „To” to… prymitywna jednostka montażowa . Tak, ta rzecz, która uruchamia się dwa razy, gdy używasz GS. Indeks pamięci podręcznej? Działa tylko w przypadku wejść GS.
Co dzieje się z wynikami GS? To zależy od sprzętu. Ale musi przejść do jakiegoś bufora pamięci. I na tym polega problem: ten bufor w ogóle nie jest indeksowany. To jest jak sytuacja glDrawArrays.
Więc jeśli wyślesz bufor indeksu 0, 1, 2, 0, 2, 3
, to przełoży się to na 4 wierzchołki w pamięci podręcznej po T & L. Ale bufor wierzchołków po GS ma teraz 6 wierzchołków. Bufor post-GS zajmuje więcej miejsca. Jeśli więc przejdziecie trud tworzenia właściwych list lub pasków trójkątów zoptymalizowanych po T & L i włączysz GS typu pass-through jak twój, w zasadzie zabiłeś około połowy zysków z tej optymalizacji.
To nie było bezużyteczne, ale boli.
Do tego dochodzi fakt, że wiele procesorów graficznych klasy GL 3.x (aka: DX10) miało raczej małe bufory post-GS. Im mniejszy bufor, tym mniej wywołań GS możesz mieć jednocześnie aktywnych. Twój sprzęt skutecznie wąskie gardła w GS. Ponieważ teselacja jest dużą cechą sprzętu klasy 4.x, większość takiego sprzętu ma bufory wystarczające, aby cięższe użycie GS było opłacalne.
Tak więc użycie GS może sprawić, że przetwarzanie wierzchołków kodu będzie wąskie. Oczywiście zawsze możesz użyć tego na swoją korzyść, czyniąc shadery wierzchołków i fragmentów bardziej złożonymi, ponieważ w tym momencie jest to po prostu darmowa wydajność.
Aby uzyskać więcej informacji na temat spowolnień wywołanych przez GS, przeczytaj ten artykuł .
Oto podstawowa zasada o GS: nigdy nie używaj GS bo myślisz uczyni rendering szybciej . Powinieneś go używać, gdy umożliwia to, co próbujesz zrobić . Jeśli próbujesz zoptymalizować, użyj czegoś innego.
Ogólne wyjątki od tego są następujące:
layout(points) in;
? Czy jest to stały rozmiar wyjściowy? A może jedno i drugie?