Estou pensando em uma cena do tipo minecraft, onde por voxel você quer dizer um mundo de blocos que são realmente renderizados usando polígonos:
Se você usar um sombreador de geometria, será difícil evitar ter exatamente três faces (ou o que for) por voxel.
Se você tiver muitos blocos adjacentes com a mesma textura, poderá usar o mosaico das texturas para ter muito menos triângulos na sua faixa (degenerada) em uma abordagem de VBO. Quero dizer, se houver uma área grande e plana 6x6 de voxels de grama, você pode desenhar o topo inteiro em apenas 2 triângulos em vez de 64.
Com a abordagem GS, você também não pode fazer o descarte trivial de faces ocluídas por voxels adjacentes, o que é muito direto com a abordagem VBO.
Eu não tentei a abordagem GS, mas posso dizer que a abordagem VBO com a combinação de repetição de blocos adjacentes funciona muito bem. Achei que mexer com os índices de elementos era muito mais lento do que apenas repetir os vértices. Se você dividir seu mundo em pequenos cubos, normalmente poderá usar apenas um byte por componente por vértice e até empacotar as informações de textura e os normais (uma face em um cubo alinhado ao eixo tem apenas três normais possíveis) etc. em um quarto byte para criar 4 bytes por vértice, o que é agradável e rápido.
Eu usei VBOs separados para cada uma das 6 faces - você só precisa desenhar no máximo 3 delas, obviamente. Isso se encaixa perfeitamente com as diferentes texturas normalmente usadas nas partes superiores dos voxels no estilo minecraft. Porque para cada conjunto o normal e tal são então uniformes.
Com o uso de pixmaps de mosaico vertical em um atlas GL_REPEAT
no eixo horizontal e com versões rotacionadas em 90 graus dos pixmaps no mesmo atlas, descobri que posso desenhar grandes quantidades de blocos aparentemente diferentes usando o mesmo VBO na mesma chamada. No exemplo da área de grama 6x6, eu o dividiria em 12 triângulos, pois só tenho repetição em uma dimensão no meu atlas.
Eu tenho conseguido que isso funcione na extremidade mais baixa de chips gráficos integrados e móveis, onde GS é apenas algo que eu posso sonhar um dia brincando.
E a terceira opção, usando matrizes instanciadas? Basicamente, você desenha muitas caixas (feitas de um cubo simples de 8 vértices) com uma única chamada de desenho, fornecendo as posições (e outros dados) como atributos por instância do VBO voxel-data (usando
glVertexAttribDivisor
no OpenGL, tenho certeza DX tem isso também). Isso pode ser mais rápido do que a abordagem de sombreador de geometria, embora o código do aplicativo (sem sombreador) deva ser bastante semelhante, pois eu me lembro de sombreadores de geometria com reputação de serem lentos, embora eu não tenha experiência com eles (ou instanciação) enquanto ainda estou sentado no hardware 2.1.Mas, de qualquer forma, shaders de geometria ou matrizes instanciadas devem ser mais adequadas que a geometria de voxel criada por CPU, especialmente quando os dados de voxel estão sujeitos a alterações. Em conjunto com o feedback de transformação (saída de fluxo no DX?), Você pode configurar uma boa técnica de seleção baseada em GPU.
fonte
A versão de sombreador de geometria me parece muito melhor. Você pode ter apenas o ponto vbo e a caixa de construção em tempo real (ponto de entrada, fluxo do triângulo de saída). Será rápido (ainda mais rápido se você usar a unidade de mosaico no shader model 5 eq. DX11) e reduzirá extremamente a largura de banda, será uma solução agradável e limpa.
Sobre a GS. Ele é colocado entre o vertex shader e o pixel shader e modifica o fluxo de vértice emitido (primitivos). Enquanto o sombreador de vértice funciona apenas nos vértices, o sombreador de geometria funciona em primitivas inteiras. A saída desse fluxo vai apenas para o pixel shader (e é rasterizada antes disso naturalmente :)) e não há como salvá-lo. (Talvez por uma renderização maluca para texturizar e depois analisá-la ... mas não há nenhuma possibilidade real)
Nota de desempenho: você deve conseguir tudo no sombreador de geometria e pular (apenas passar dados) o sombreamento de vértice. Mas não é o melhor caminho. Melhor (mais rápido) é fazer a maior parte da transformação possível no sombreador de vértice e tentar minimizar o programa de sombreamento de geometria. Não tenha medo de usar o ciclo se precisar (para criação de caixas, por exemplo). O compilador desenrolará para você.
fonte