Non è esattamente ciò che OpenGL stava facendo senza lo shader della geometria?
No, non lo è. GS è un passaggio facoltativo , non un passaggio con un valore predefinito.
Affinché OpenGL esegua uno shader di geometria , deve eseguire quello che è noto come " assembly primitivo ". Quando si GL_TRIANGLE_STRIP
esegue il rendering di una serie di triangoli tramite , OpenGL eseguirà operazioni interne per convertire ogni 3 vertici adiacenti in un singolo triangolo, modificando l'ordine di avvolgimento in modo appropriato.
Normalmente, quando non si utilizza un GS, questo processo viene eseguito una volta. Quando si utilizza un GS, tuttavia, deve essere eseguito prima dell'esecuzione di GS. Ma deve anche essere eseguito dopo il GS, perché un GS può produrre un tipo primitivo completamente diverso (ad es. Quad).
Quindi ora stai facendo praticamente al sistema un sacco di lavoro extra per niente. Dopotutto, OpenGL non può presumere che il tuo GS non stia facendo nulla (questo è un problema indecidibile).
Inoltre, una serie di ottimizzazioni non funzionano più in presenza di un GS. Prendi in considerazione il rendering indicizzato.
Ogni indice da un buffer di array di elementi produrrà gli stessi output da uno shader di vertici. Così la GPU sarà spesso nella cache queste uscite in una cache post-T & L . Se vede un indice che è già nella cache, il VS non viene eseguito di nuovo; recupera solo i dati dalla cache.
Che cos'è"? "It" è ... l' unità di assemblaggio primitiva . Sì, quella cosa che viene eseguita due volte quando usi un GS. L'indice memorizza nella cache? Funziona solo per gli ingressi del GS.
Quindi cosa succede alle uscite della GS? Bene, dipende dall'hardware. Ma deve andare in una sorta di buffer di memoria. E qui sta il problema: quel buffer non è affatto indicizzato. È come una situazione glDrawArrays.
Quindi, se si invia un buffer di indice di 0, 1, 2, 0, 2, 3
, questo si tradurrebbe in 4 vertici nella cache post-T & L. Ma il buffer dei vertici post-GS ora contiene 6 vertici. Il buffer post-GS utilizza più spazio. Quindi, se hai il problema di creare elenchi di triangoli o strisce correttamente ottimizzati post-T & L, e capovolgi una GS pass-through come la tua, fondamentalmente hai ucciso circa la metà dei tuoi guadagni in termini di prestazioni da tale ottimizzazione.
Non era inutile, ma fa male.
A ciò si aggiunge il fatto che molte GPU di classe GL 3.x (aka: DX10) avevano buffer post-GS piuttosto piccoli. Più piccolo è il buffer, meno invocazioni GS puoi avere attivo contemporaneamente. In questo modo il tuo hardware si colloca efficacemente sul GS. Poiché la tassellatura è una grande caratteristica dell'hardware di classe 4.x, la maggior parte di tali hardware ha buffer sufficienti per rendere praticabile l'utilizzo di GS più pesante.
Quindi l'uso di un GS ha maggiori probabilità di rallentare l'elaborazione del vertice del codice. Ovviamente, puoi sempre usarlo a tuo vantaggio rendendo i tuoi shader di vertici e frammenti più complessi, dal momento che sono solo prestazioni gratuite a quel punto.
Per ulteriori informazioni sui rallentamenti indotti da GS, leggi questo articolo .
Ecco una regola empirica di base sui GS: non usare mai un GS perché pensi che renderà il rendering più veloce . Dovresti usarlo quando rende possibile ciò che stai cercando di fare . Se quello che stai cercando di fare è un'ottimizzazione, usa qualcos'altro.
Le eccezioni generali a questo sono: