Estou escrevendo um aplicativo que processa uma ilha aleatória plantada com árvores. As árvores são atualmente dois quadriláteros, cruzados e desenhados com texturas. Planejo ter malhas mais complexas que formem diferentes tipos de plantas, como palmeiras, carvalhos, gramíneas etc.
O problema que enfrento é que, como as texturas são transparentes, preciso desenhá-las de trás para frente. O plano-b é usar o descarte no frag shader, mas a ordem z fornece melhores resultados:
uniform float uTreeAlpha;
uniform sampler2D uTexture;
varying vec2 vTexCoordOut;
void main (void)
{
vec4 colour = texture2D(uTexture, vTexCoordOut);
if (colour.a < 0.1) {
discard;
}
gl_FragColor = vec4(colour.rgb, colour.a * uTreeAlpha);
}
O segundo problema é que a ordem muda dependendo da câmera e da aparência. Não conheço uma maneira eficiente de desenhá-las no OpenGL em uma única chamada.
Atualmente, meu código de renderização se parece com este pseudocódigo:
if cameraChangedFromLastTime() then
sortTreesBackToFront();
end
for i = 0 to trees.size() -1
drawTree()
end
Onde todo drawTree () define alguns uniformes, define a textura e chama glDrawArrays (). Eu tenho algumas otimizações para pular a configuração de uma textura ou atualizar as cordas de textura, se a última árvore e a corrente forem iguais, e definir alguns uniformes comuns fora do loop e pular árvores que estão muito distantes, mas basicamente se eu tiver 3000 árvores I ir 3000 vezes ao redor do loop.
Desenhar cada árvore individualmente é o assassino de desempenho. Se eu pudesse desenhá-los em uma única chamada ou em lotes (preservando a ordem Z), provavelmente o faria em 1/10 do tempo.
Então, como eu faria isso. Lembre-se de que minhas árvores são espaços reservados e, eventualmente, eu teria:
- Malhas diferentes para árvores diferentes
- Diferentes escalas e ângulos para as árvores para dar um pouco mais de variedade
- Texturas diferentes para árvores diferentes, potencialmente várias texturas aplicadas a uma malha (por exemplo, deixa uma textura, tromba outra)
- As árvores são todas misturadas, portanto, não há maneira simples de desenhar um tipo e depois outro
- Alguma forma de animação cíclica simples (galhos balançando ao vento)
- Todas as texturas residiriam em um único atlas
Então, qual é a melhor abordagem aqui? É possível renderizar em uma única passagem? Se eu usasse glDrawElements, reconstruindo os índices, mas não os vértices, conseguiria isso?