Não é exatamente isso que o OpenGL estava fazendo sem o sombreador de geometria?
Não é não. O GS é uma etapa opcional , não uma etapa que possui um padrão.
Para que o OpenGL execute um sombreador de geometria , ele deve executar o que é conhecido como " montagem primitiva ". Quando você renderiza uma série de triângulos GL_TRIANGLE_STRIP
, o OpenGL faz coisas internas para converter a cada 3 vértices adjacentes em um triângulo individual, modificando a ordem do enrolamento de maneira apropriada.
Normalmente, quando não se usa um GS, esse processo é realizado uma vez. No entanto, quando você usa um GS, ele deve ser executado antes da execução do GS. Mas também deve ser realizado após o GS, porque um GS pode gerar um tipo primitivo totalmente diferente (por exemplo, quads).
Então agora você está fazendo o sistema basicamente fazer um monte de trabalho extra por nada. Afinal, o OpenGL não pode assumir que seu GS não está fazendo nada (esse é um problema indecidível).
Além disso, várias otimizações não funcionam mais na presença de um GS. Considere a renderização indexada.
Cada índice de um buffer de matriz de elementos produzirá as mesmas saídas de um sombreador de vértice. Portanto, a GPU geralmente armazena essas saídas em cache em um cache pós-T&L . Se ele vir um índice que já está no cache, o VS não será executado novamente; apenas busca dados do cache.
O que é isso"? "It" é ... a unidade de montagem primitiva . Sim, aquela coisa que é executada duas vezes quando você usa um GS. O material de armazenamento em cache do índice? Funciona apenas para as entradas do GS.
Então, o que acontece com as saídas do GS? Bem, isso depende do hardware. Mas tem que entrar em algum tipo de buffer de memória. E aí está o problema: esse buffer não está indexado. É como uma situação glDrawArrays.
Portanto, se você enviar um buffer de índice de 0, 1, 2, 0, 2, 3
, isso se traduziria em 4 vértices no cache pós-T&L. Mas o buffer de vértices pós-GS agora possui 6 vértices. O buffer pós-GS usa mais espaço. Portanto, se você enfrentar o problema de criar listas ou tiras de triângulo otimizados pós-T&L adequadamente e usar um GS de passagem como o seu, basicamente matará cerca de metade dos seus ganhos de desempenho com essa otimização.
Não foi inútil, mas dói.
Além disso, muitas GPUs da classe GL 3.x (aka: DX10) tinham buffers pós-GS bastante pequenos. Quanto menor o buffer, menos invocações de GS você pode ter ativo simultaneamente. Portanto, seu hardware efetivamente afunila a GS. Como o mosaico é um grande recurso do hardware da classe 4.x, a maioria desses hardwares possui buffers suficientes para viabilizar o uso mais pesado de GS.
Portanto, é mais provável que o uso de um GS faça com que seu processamento de vértice de código seja afunilado. Obviamente, você sempre pode usar isso a seu favor, tornando seus shaders de vértice e fragmento mais complexos, já que é apenas um desempenho gratuito nesse ponto.
Para obter mais informações sobre lentidão induzida por GS, leia este artigo .
Aqui está uma regra básica sobre os GS: nunca use um GS porque você acha que isso tornará a renderização mais rápida . Você deve usá-lo quando isso possibilitar o que você está tentando fazer . Se o que você está tentando fazer é uma otimização, use outra coisa.
As exceções gerais a isso são:
layout(points) in;
? Ou é o tamanho de saída fixo? Ou talvez ambos?