Je développe un jeu 2D et j'ai beaucoup de sprites. J'ai utilisé des animations et des modèles 3D pour effectuer un rendu en 2D, pour leur donner un aspect "Fallout" ou "Diablo". C'est aussi plus facile que de dessiner à la main, lol.
J'ai déjà dû réduire le framerate à 15 images par seconde, ce qui était le plus bas que je pouvais abaisser sans leur donner un aspect saccadé. Cependant, c'était triste à cause de la fluidité incroyable de 24 images.
Il y a deux raisons pour lesquelles j'ai fait cela:
1) Réduisez l'espace disque dur. Moins il y a d'images, plus mon jeu sera petit.
2) Réduisez la consommation de RAM. Moins il y a d'images à charger, plus j'ai de chances d'éviter les problèmes de gonflement de ma limitation de RAM.
Cependant, s'il y avait un moyen de compresser les images dans l'espace disque dur et la RAM, je le ferais. Je l'ai testé auparavant, et la plupart ne reçoivent aucun changement de qualité lors du passage de RGBA8888 à RGBA5555 et seulement un petit coup lors de la conversion en RGBA4444 dans mon programme TexturePacker. Je ne le fais pas actuellement, car SFML semble utiliser la même quantité de mémoire quel que soit le type d'image .PNG dont il s'agit. J'ai cherché à le charger différemment, mais je n'ai rien trouvé sur le sujet.
J'ai beaucoup lu sur la façon de gérer les jeux vidéo 2D. Le consensus est écrasant: emballez vos Sprites dans une texture plus grande pour de grandes performances! J'ai donc emballé mes minuscules sprites dans une feuille de sprites beaucoup plus grande en utilisant TexturePacker.
Cependant, je prévois d'avoir 10 à 15 animations par personnage, 5 directions pour se déplacer et 15 à 40 images par animation (probablement une moyenne de 24). Avec 15 animations, 5 directions et une moyenne de 24 images par animation; Soit 1800 images individuelles par caractère. S'il est emballé dans une feuille de sprite, cela ne représente que 75 images à la place. (Une feuille de sprite par animation, par direction. 15 * 5)
Pour le seul grand boss du jeu, je ne peux pas utiliser de feuille de calcul et je dois programmer un moyen de charger simplement une image à la fois. Je ne sais pas encore si je peux le faire pour la performance.
Pour les personnages, je les ai déjà emballés dans une feuille de sprites. Pour un seul personnage qui se promène, cela semble fonctionner la plupart du temps, même si parfois cela cale. Cependant, j'attribue cela à mon code mal conçu qui permute les textures au lieu de précharger toutes les textures pour ce personnage.
Si je devais précharger les textures, cela a du sens pour les feuilles de sprite. J'imagine que c'est une mauvaise idée de précharger 1800 minuscules images pour chaque personnage.
Cependant, j'imagine que les diffuser dans et hors de la mémoire une par une serait extrêmement rapide, donc je n'aurais besoin que d'une seule image en mémoire à la fois. Cela ne signifierait-il pas qu'à un moment donné, je ne ferais que consommer par Ko quelques caractères au lieu de 45 + Mo?
J'imagine que cela tuerait mes performances, car le streaming devrait être incroyablement rapide (15 images entrant et sortant de la mémoire et du rendu, par seconde) et bien que les images soient très petites, il serait peut-être préférable de charger des feuilles de sprites de caractères en mémoire à la place. Mais je devrai quand même coder un système de rendu de type image unique pour mon plus grand personnage.
J'ai expérimenté, mais ce n'est pas un processus simple. Surtout étant donné que je travaille sur d'autres parties du moteur de jeu qui ne traitent pas actuellement avec les graphismes.
Réponses:
Nous avons un cas similaire avec notre remake RTS. Toutes les unités et maisons sont des sprites. Nous avons 18 000 sprites pour les unités, les maisons et le terrain, plus ~ 6 000 pour les couleurs des équipes (appliquées comme masques). Long-étiré, nous avons également environ 30 000 caractères utilisés dans les polices.
Donc, la principale raison derrière les atlas est:
Ce qui n'a pas fonctionné pour nous:
Maintenant, nous avons tout emballé dans plusieurs dizaines d'atlas 1024x1024 (les GPU modernes prennent en charge des dimensions encore plus grandes) et cela fonctionne très bien en ne consommant que ~ 300 Mo de mémoire, ce qui est très bien pour un jeu PC. Quelques optimisations que nous avons eues:
Lorsque vous envisagez sérieusement de passer à des appareils mobiles, vous vous inquiétez des contraintes. Pour l'instant, lancez le jeu et attirez les joueurs! ;)
la source
J'ai une réponse tangentielle ici , mais l'idée générale est que, si vous chargez et dessinez des textures à des moments différents (vous ne chargez pas de textures supplémentaires pendant le rendu), il y a deux endroits où ce que vous cela affectera vos performances:
Temps de chargement:
C'est le moment où vous téléchargez vos textures en mémoire. La quantité totale de données que vous envoyez à VRAM est ce qui définira principalement la durée de votre chargement. Faire de vos textures des formats plus petits, comme RGBA4444, rendra cela plus rapide. Cependant, à moins que vous ne téléchargiez des textures de centaines de mégaoctets sur VRAM, vous n'aurez probablement pas de goulot d'étranglement ici. Si vous le faites, un joli écran de chargement peut faciliter l'attente.
Joindre vos textures dans des atlas aura peu d'effet, car la quantité totale d'informations que vous envoyez dans VRAM sera la même. En fait, si vous atlasez vos textures et que vous devez laisser des espaces vides dans vos atlas, vous enverrez en fait plus de données dans la VRAM, et donc cette partie sera plus lente!
Performances de rendu:
Une fois que toutes vos textures sont en VRAM, la quantité de textures que vous avez n'affectera pas les performances de rendu. Quatre éléments affectent vos performances de rendu:
Modifications de l'état du rendu : chaque fois que vous modifiez l'image à partir de laquelle vous souhaitez effectuer le rendu, le temps nécessaire pour le rendre augmente considérablement. En général, vous souhaitez minimiser la quantité de changements d'état et vous pouvez réduire la quantité de changements d'état en regroupant plusieurs images que vous dessinerez consécutivement dans un atlas de texture.
L'atlas ne suffit pas. Vous devez atlaser de manière à réduire les changements d'état afin d'obtenir des gains de performances. Par exemple, on peut penser que le fait d'avoir votre personnage principal dans une feuille de sprite vous donnera un gain de performances, mais si vous ne dessinez qu'un sprite à partir de cette feuille de sprite par image, vous n'obtiendrez aucun gain de performances par rapport à avoir chaque sprite dans un fichier séparé.
Un bon atlas n'est pas anodin, mais en général, vous pouvez regrouper en toute sécurité les sprites de la même couche. Par exemple, avoir tous les éléments de l'interface graphique dans une seule feuille de sprite est une idée très prometteuse, alors que le regroupement alphabétique des monstres peut ne pas l'être.
Appeler des appels: En général, vous souhaiterez peut-être limiter au maximum vos appels. Une bonne règle est que s'il n'y a pas de changement d'état de rendu entre deux appels de tirage, vous pouvez les joindre en un seul appel de tirage. Pour des gains de performances plus avancés, vous pouvez utiliser, par exemple, 8 échantillonneurs de texture et des appels de dessin de groupe pour toutes les 8 textures, vous n'avez donc qu'à changer les textures toutes les 8 textures.
Nombre de triangles: en fait, plus vous dessinez de triangles, plus il vous faudra de temps pour les dessiner. Cependant, dans les ordinateurs modernes, et pour la plupart des jeux 2D, vous serez très loin de maximiser cela. Vous pouvez dessiner en toute sécurité des centaines de milliers de sprites par image tout en obtenant des fréquences d'images incroyablement bonnes. Vous serez probablement plus lié au processeur si vous dessinez des quantités extrêmes de sprites avant de rencontrer des problèmes avec votre GPU.
Paramètres API: si vous faites tout correctement et que vous obtenez toujours des fréquences d'images étrangement basses, vérifiez les paramètres avec lesquels vous dessinez vos sprites. Je ne connais pas SFML, mais par exemple, dans Direct3D 9, la création d'un tampon de vertex avec
D3DUSAGE_DYNAMIC
ou dansD3DPOOL_MANAGED
peut facilement décupler votre temps de rendu. Bien sûr, l'utilisation de vSync plafonnera votre taux de rafraîchissement au taux de rafraîchissement de votre moniteur. En outre, l'utilisation de FVF non alignés peut réduire les performances de certains GPU. Cela aussi, c'est pour Direct3D 9.Dans votre cas, consultez la documentation de l'API que vous utilisez.
Si vous ne disposez que d'une quantité de textures faible à modérée (moins de 1 Go) et que vous dessinez de faibles quantités de sprites (moins d'un million par image), la première chose que je regarderais serait de changer les paramètres de l'API, et puis en réduisant la quantité d'états de rendu et d'appels d'appel.
la source