Je suis en train de développer un jeu 2D basé sur les sprites pour les plates-formes mobiles et j'utilise OpenGL (enfin, en fait Irrlicht) pour rendre les graphiques. J'ai d'abord implémenté le rendu de sprite de manière simple: chaque objet de jeu est rendu sous forme de quadruple avec son propre appel de dessin GPU, ce qui signifie que si j'avais 200 objets de jeu, je faisais 200 appels de dessin par image. Bien sûr, ce n'était pas un bon choix et mon jeu était complètement lié au processeur car il y a un petit supplément de processeur associé à chaque appel de GPU. Le GPU est resté inactif la plupart du temps.
Maintenant, je pensais pouvoir améliorer les performances en collectant des objets en grands lots et en rendant ces lots avec seulement quelques appels de dessin. J'ai implémenté le traitement par lots (pour que chaque objet de jeu partageant la même texture soit rendu dans le même lot) et j'ai pensé que mes problèmes avaient disparu ... seulement pour découvrir que ma fréquence d'images était encore plus basse qu'auparavant.
Pourquoi? Eh bien, j'ai 200 (ou plus) objets de jeu, et ils sont mis à jour 60 fois par seconde. Chaque image, je dois recalculer une nouvelle position (translation et rotation) pour les sommets du CPU (le GPU sur les plates-formes mobiles ne prend pas en charge l'instanciation donc je ne peux pas le faire là-bas), et faire ce calcul 48000 par seconde (200 * 60 * 4 depuis chaque sprite a 4 sommets) semble tout simplement trop lent.
Que puis-je faire pour améliorer les performances? Tous les objets du jeu se déplacent / tournent (presque) à chaque image, donc je dois vraiment recalculer les positions des sommets. La seule optimisation à laquelle je pouvais penser est une table de correspondance pour les rotations afin de ne pas avoir à les calculer. Les sprites ponctuels seraient-ils utiles? Des hacks méchants? Rien d'autre?
Merci.
la source
Je recommanderais d'avoir un VBO, chaque sommet contenant la position / rotation de chaque objet rendu et le traitement par lots basé sur la texture comme vous le faites. Je ne suis pas très familier avec ogl ES, donc je ne sais pas quelle version de glsl il prend en charge, mais vous pourriez même être en mesure de créer un lot basé sur un ensemble de textures, et de stocker laquelle des 4 textures que vous passez en vous utiliseriez à l'intérieur du sommet. Les sprites ponctuels amélioreraient certainement vos performances, car cela réduirait considérablement la quantité de données que vous envoyez, et le traitement par lots ne devrait jamais diminuer les performances si vous le faites correctement. En outre, vous pouvez améliorer un peu les performances en calculant la rotation sur le shader et en passant uniquement une valeur int / float dans les paramètres ou à l'intérieur du sommet lui-même. (les paramètres seraient plus rapides,
la source
Vous mentionnez des plateformes mobiles qui n'ont pas d'instanciation. Mais, vous avez toujours des vertex shaders, n'est-ce pas?
Dans ce cas, vous pouvez toujours faire une pseudo instanciation, ce qui est également très rapide. Faire un VBO (GL_STATIC_DRAW) avec les points d'angle (par rapport au point central du sprite, par exemple -1 / -1, 1 / -1, 1/1, -1/1) et toutes les coordonnées de texture dont vous avez besoin, en lui .
Ensuite, définissez l'un des attributs de sommet génériques pour chaque appel de dessin au point central du sprite et dessinez les deux triangles avec le tampon lié. À l'intérieur du vertex shader, lisez l'attribut générique du sommet et ajoutez les coordonnées du sommet.
Cela vous évitera de bloquer un transfert de données pour chaque sprite et devrait être beaucoup plus rapide. Le nombre réel d'appels de tirage n'est pas si important, le blocage / le blocage entre les deux l'est.
la source
Le problème réside dans la quantité de données que vous envoyez au GPU à chaque trame. Créez simplement un VBO pour chaque lot et remplissez-le une fois, puis appliquez les matrices de transformation correspondantes (via glMultMatrix ou un shader si vous utilisez ES 2.0) lors du dessin des lots.
la source