J'écris une application qui rend une île aléatoire plantée d'arbres. Les arbres sont actuellement deux quads, entrecroisés et dessinés avec des textures. Je prévois d'avoir des mailles plus complexes qui forment différents types de plantes, par exemple un palmier, un chêne, des herbes, etc.
Le problème auquel je suis confronté est que parce que les textures sont transparentes, je dois les dessiner de l'arrière vers l'avant. Le plan-b consiste à appeler l'utilisation de la suppression dans le shader de frag, mais l'ordre z donne de meilleurs résultats:
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);
}
Le deuxième problème est dû au fait que l'ordre change en fonction de la caméra et du look. Je ne connais pas de moyen efficace de les dessiner en OpenGL en un seul appel.
À l'heure actuelle, mon code de rendu ressemble à ce pseudocode:
if cameraChangedFromLastTime() then
sortTreesBackToFront();
end
for i = 0 to trees.size() -1
drawTree()
end
Où chaque drawTree () définit des uniformes, définit la texture, puis appelle glDrawArrays (). J'ai quelques optimisations pour ignorer la définition d'une texture ou la mise à jour des coords de texture si le dernier arbre et le courant sont les mêmes, et la mise en place d'uniformes communs en dehors de la boucle, et de sauter des arbres qui sont trop éloignés mais, fondamentalement, si j'ai 3000 arbres, je faire 3000 fois le tour de la boucle.
Dessiner chaque arbre individuellement est le tueur de performance. Si je pouvais les dessiner en un seul appel, ou en lots (tout en préservant l'ordre Z), je le ferais probablement au 1 / 10e du temps.
Alors, comment pourrais-je faire cela. Gardez à l'esprit que mes arbres sont des espaces réservés et, éventuellement, j'aurais:
- Différentes mailles pour différents arbres
- Différentes échelles et angles pour les arbres pour donner plus de variété
- Différentes textures pour différents arbres, potentiellement plusieurs textures appliquées à un maillage (par exemple, laisse une texture, tronc une autre)
- Les arbres sont tous mélangés, donc pas de moyen simple de dessiner une sorte puis une autre
- Une certaine forme d'animation cyclique simple (branches flottant dans le vent)
- Toutes les textures résideraient dans un seul atlas
Alors, quelle est la meilleure approche ici? Est-il possible de rendre en un seul passage? Si j'utilisais glDrawElements, reconstruisant les indices mais pas les sommets, pourrais-je y parvenir?