Graphiques 2D - Pourquoi utiliser des feuilles de calcul?

62

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.

Columbo
la source
Non, cela n'a pas vraiment d'importance pour vos 50 sprites. Mais que faut-il perdre?
Le canard communiste

Réponses:

69

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.

bummzack
la source
1
Merci, je n'avais pris en compte aucun de ces points - Savez-vous approximativement quelle est la limite sur le nombre de textures disponibles? Je n'ai jamais vu cette statistique mentionnée dans les spécifications graphiques - la limite est-elle fondamentalement égale à la quantité de RAM graphique?
Columbo
Habituellement, la limite serait la mémoire du GPU, oui. Je pensais qu'il y avait des restrictions sur le nombre de textures sur les anciennes cartes mais je n'arrive pas à trouver une référence qui le prouve.
Bummzack
12
Même s'il n'y a pas de limite de quantité, le trafic de bus pour déplacer beaucoup de petites images n'est pas aussi efficace qu'un (ou plusieurs) grand (s) transfert (s).
Mordachai
5
Bons points, mais l’aspect le plus important est de minimiser les blocages de pipeline en limitant le compte d’appel. Les GPU préfèrent un petit nombre de gros travaux plutôt qu'un grand nombre de petits travaux. En mettant tous vos sprites dans une petite quantité de grandes feuilles, vous pouvez configurer le stade de texte une fois et dessiner de nombreux sorts à la fois dans un lot. Spritebatch le fait pour vous. Si vous avez plus d'une feuille de sprites, assurez-vous de dire à spritebatch de trier les textures
Cubed2D
Ajouter de la compression de texture transformerait n'importe quel espace inutilisé en une très petite quantité de frais généraux, en plus de tout cela
Joe Plante
36

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.

Roger Perkins
la source
2
+1 Touches lors d'appels de tirage. (quelque chose que je n'ai pas vu dans la réponse acceptée)
Michael Coleman
11

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.

Tetrad
la source
2
Cela compte toujours. Le matériel graphique a été optimisé pour déplacer des tonnes de polygones dans un petit nombre de modèles détaillés (par exemple, des personnages), car la plupart des jeux ont tendance à aller dans cette direction. Le résultat est que vous devez pousser autant de polygones que possible dans chacun des quelques dizaines d'appels dessinés. Les moteurs de jeu qui rendent de grandes scènes comme des villes combinent souvent plusieurs textures en une à la volée afin de réduire les appels de dessin.
route le
Je me demande vraiment si le mappage de texture u, v dans beaucoup de matériel 3D, ainsi que les opérations de blitting de bits tirent profit de la feuille de sprite.
Joe Plante
7

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.

Gregory Avery-Weir
la source
1
+1 Bien que l'OP n'utilise pas Flash, l'incorporation ou le chargement est également un argument en faveur des feuilles de sprites. Cela est également pertinent lorsque les ressources sont chargées depuis un serveur Web où une requête est préférée à plusieurs centaines de requêtes (pour chaque "cadre").
Bummzack
Vous voulez certainement réduire les demandes du serveur pour un jeu en ligne. Nous avons examiné s'il était préférable de placer les images dans un fichier .swf ou une feuille de style car les deux atteignent cet objectif principal (nous avons finalement décidé que les feuilles de calcul nécessitent moins de main-d'œuvre pour nos artistes).
Jhocking
7

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.

George Clingerman
la source
5

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.

Le canard communiste
la source
4

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.

comonad
la source
3

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).

Marquage
la source
1
Dans l’autre extrémité, si vous souhaitez résoudre le problème de recherche de fichier, vous pouvez regrouper tous vos sprites dans un seul fichier, en utilisant un format personnalisé. La plupart des jeux font ça.
Tigrou
0

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:

sheet = {
    img: (the actual image),
    rects: [
        {x:0, y:0, w:32, h:32},
        {x:32, y:0, w:32, h:32},
        {x:64, y:0, w:32, h:32}
    ]
};

sheets.push(sheet);

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.

Bridgerrholt
la source