J'ai vu de nombreux exemples sur la manière de restituer des sprites à partir d'un spritesheet, mais je n'ai pas compris en quoi c'est le moyen le plus courant de traiter les sprites dans des jeux en 2D.
Dans les quelques applications de démonstration que j'ai créées, j'ai commencé avec le rendu des sprites en traitant chaque image d'animation pour un type de sprite donné comme sa propre texture - et cette collection de textures est stockée dans un dictionnaire. Cela semble fonctionner pour moi et convient assez bien à mon flux de travail, car j'ai tendance à créer mes animations en tant que fichiers gif / mng, puis à extraire les images au format png individuel.
Existe-t-il un avantage de performance notable en ce qui concerne le rendu à partir d'une seule feuille plutôt que de textures individuelles? Avec un matériel moderne capable de dessiner des millions de polygones sur l'écran cent fois par seconde, est-ce que cela compte même pour mes jeux en 2D qui ne traitent que quelques dizaines de rectangles de 50 x 100 pixels?
Les détails de l’implémentation du chargement d’une texture dans la mémoire graphique et de son affichage dans XNA semblent assez abstraits. Tout ce que je sais, c'est que les textures sont liées au périphérique graphique lors de leur chargement, puis pendant la boucle de jeu, les textures sont rendues par lots. Je ne vois donc pas clairement si mon choix affecte les performances.
Je soupçonne qu'il y a de très bonnes raisons pour lesquelles la plupart des développeurs de jeux en 2D semblent les utiliser, je ne comprends tout simplement pas pourquoi.
la source
Réponses:
Un argument de poids en faveur de l'utilisation de feuilles de sprites est que le nombre de textures disponibles sur une carte graphique peut être limité. Par conséquent, votre bibliothèque graphique devra constamment supprimer les textures et réaffecter les textures sur le GPU. Il est bien plus efficace d’attribuer une seule fois une texture volumineuse.
Considérez également que les tailles de texture ont généralement une puissance de 2. Donc, si vous avez un Sprite 50x100px, vous affecterez des textures de taille 64x128px ou, dans le pire des cas, de 128x128px. C'est juste gaspiller de la mémoire graphique. Mieux emballer tous les sprites dans une texture 1024x1024px, ce qui permettrait 20x10 sprites et vous ne perdrez que 24 pixels horizontalement et verticalement. Parfois, même des images-objets de tailles différentes sont combinées en une seule feuille-objet pour utiliser la texture le plus efficacement possible.
Addendum: Une raison très importante d'utiliser des feuilles de sprite est de réduire le nombre d'appels de tirage sur votre GPU, ce qui peut avoir un impact notable sur les performances. Cela a été dit dans d'autres réponses et j'ajoute ceci dans un souci de complétude afin que cela devienne plus visible.
la source
Je dirais que l'argument à utiliser serait la possibilité de rendre plusieurs choses en un seul appel de tirage au sort. Prenons, par exemple, le rendu des polices. Sans feuille de sprite, il vous faudrait rendre chaque caractère avec un échange de texture séparé suivi d'un appel de dessin. Jetez-les dans une feuille de sprites et vous pouvez restituer des phrases entières en un seul appel de tirage (les caractères de différence dans la police sont sélectionnés en spécifiant simplement les différents UV pour les coins). C’est un moyen de rendu beaucoup plus efficace lorsqu’un trop grand nombre de tâches de rendu sur de nombreuses plates-formes consiste à faire trop d’appels d’API.
Cela peut aussi aider à économiser de la place, mais cela dépend de ce que vous insérez dans la feuille de sprite en premier lieu.
la source
Chaque appel de tirage a une certaine quantité de frais généraux. En utilisant des feuilles d'image-objet, vous pouvez regrouper par lots le dessin d'éléments qui n'utilisent pas la même image d'une animation (ou plus généralement, tout ce qui se trouve sur le même matériau), ce qui améliore considérablement les performances. Cela dépend peut-être moins pour les PC modernes en fonction de votre jeu, mais cela compte vraiment sur, par exemple, l'iPhone.
la source
Outre les considérations relatives aux performances, les feuilles d’image-objet peuvent être pratiques lors de la création de l’art; chaque caractère peut être dans sa propre feuille, et vous pouvez voir tous les cadres simplement en les faisant défiler. Cela m'aide à garder un regard cohérent sur tous les cadres.
De plus, je code en AS3 et chaque fichier image nécessite une instruction d'intégration distincte. Je préférerais avoir une seule incorporation d'une feuille de sprite entière que de 24 incorporées pour toutes les images, même si j'utilise une classe de ressources séparée.
la source
Une autre raison d'utiliser les feuilles de calcul avec XNA est qu'avec le développement Xbox 360, il existe un problème connu lié à la lenteur du déploiement / chargement par rapport au nombre de fichiers que vous avez dans votre projet. Donc, combiner beaucoup de petits fichiers image dans un seul fichier image aidera à lutter contre ce problème.
la source
Je ne vais pas parler de mémoire / GPU ici, car il y a assez de réponses comme ça.
Au lieu de cela, il peut éclaircir votre art pendant que vous y travaillez - et après. Au lieu d'avoir à feuilleter 10 images pour voir le cycle de marche, vous pouvez voir toutes les images en une fois. Si vous voulez distribuer ceci, vous n'avez qu'un seul fichier à traiter au lieu de 10.
Et puis, il est également préférable (du point de vue de l'organisation) d'avoir character.png et ennemi.png sur characterwalk01 jusqu'à characterwalk10, puis characterattack01 à characterattack05, et ainsi de suite.
la source
La mémoire graphique n’a pas de gestion de mémoire gonflante comme les systèmes de fichiers sur disques; le contraire est le cas: il reste simple et rapide .
Une telle gestion simple et rapide de la mémoire pourrait ressembler à un seul sprite géant 4096x4096 coupé en plusieurs sprites plus petits en réduisant de moitié sa largeur et / ou sa hauteur. (Il existe une technique similaire de gestion de la mémoire unidimensionnelle, mais j’ai oublié le nom.) Finalement, la défragmentation doit être effectuée.
Pour ignorer cette gestion de la mémoire au moment de l' exécution , les développeurs remplissent automatiquement des sprites de grande taille avec plusieurs sprites plus petits au moment de la compilation ou même au cours du processus de conception des graphiques.
la source
N'oubliez pas non plus les opérations d'E / S qui pourraient vous sauver lors de l'initialisation. Si vous chargez à partir d'un lecteur de CD, chaque fichier est un appel d'E / S supplémentaire et peut prendre un certain temps à rechercher (les disques durs modernes mesurent environ 15 ms, les CD peuvent atteindre 50 à 100 ms?). Cela peut vous faire gagner beaucoup de temps d'initialisation, car un seul fichier doit être récupéré. Cela permet également à votre système d'exploitation de mettre en cache ces opérations d'E / S, au cas où votre application ferait autre chose (comme attendre un GPU).
la source
Autre que d’être plus efficace en termes de performance, je le trouve tout simplement plus facile. Il faut un peu plus de travail pour vous assurer que vos images sont toujours dans les limites de la création, mais il est beaucoup plus facile de voir toutes les images que vous utilisez actuellement.
C'est aussi plus facile à coder, à mon avis. J'ai simplement un tableau d'objets comme:
Ensuite, pour chaque élément, je lui donne deux valeurs, feuille et rect. La feuille serait l'index dans le tableau d'objets, et le rect serait l'index dans le tableau de résultats de cette feuille.
la source