Optimiser un jeu XNA 2D

56

Est-il judicieux d'implémenter la logique pour ignorer le rendu d'objets en dehors de la fenêtre d'affichage ou devrais-je ne pas m'en soucier et laisser le Framework le faire?

smnbss
la source

Réponses:

79

L'abattage est une optimisation de la performance. Donc, cela n'a pas de sens de le faire juste pour le plaisir de le faire. Vous devez avoir une raison.


Le GPU (pas le XNA Framework) élimine les triangles et les pixels à une vitesse aveuglante. Chaque triangle que vous soumettez doit être transformé (via votre vertex shader). Ensuite, il élimine ceux qui atterrissent hors écran. Ensuite, il remplit les triangles restants, en éliminant les pixels hors écran. Les pixels restants sont ensuite dessinés dans la mémoire tampon arrière (via votre pixel shader).

(Quand je dis "alors" - il fait tout cela dans un pipeline massivement parallèle.)

Il est donc très rare et inhabituel d’avoir à sélectionner des triangles individuels. Pour atteindre les limites de sommet, vous devez dessiner un nombre absurdement grand de triangles. Pour atteindre les limites de taux de remplissage, d'extraction de texture ou d'ombrage des pixels, vous devez généralement disposer d'une complexité de profondeur élevée (dans ce cas, l'élimination de la fenêtre de visualisation / frustum ne vous aidera pas).


Il n'y a donc généralement que peu ou pas de coût à avoir une géométrie hors écran.

Le coût - en particulier dans le contexte du dessin "d'objets" (généralement des objets 3D) - réside en réalité dans la soumission de ces objets au GPU en premier lieu . Soumettez trop d'objets et vous atteignez votre limite de lots (vous obtenez quelques milliers de * lots par image).

Je vous recommande de lire cette réponse et cette diapositive associée pour une description détaillée des lots.

De ce fait, si vous implémentez la suppression des ruptures, vous pouvez réduire le nombre de lots que vous soumettez au GPU. Si vous êtes limité par lots - cela peut vous amener sous la limite.


Maintenant - votre question concerne 2D XNA - donc vous utilisez probablement SpriteBatch. C'est un peu différent

Ce n’est pas une erreur qu’on l’appelle "Sprite Batch ". Ce qu'il fait est de prendre les sprites de dessiner et de faire le mieux possible de soumettre ces sprites au GPU en tant que quelques lots que possible en les Batching ensemble.

Mais SpriteBatch sera obligé de démarrer un nouveau lot si:

  • Vous dessinez plus d'images-objets qu'il ne peut en contenir dans un seul lot (2048 images-objets dans XNA 4)
  • Vous changez de texture (c'est pourquoi il existe une option de tri par texture)

L'abattage est donc une optimisation appropriée si vous rencontrez le premier. Si vous envoyez un nombre tellement important de sprites, vous vous retrouvez avec trop de lots (vous utilisez probablement aussi de la bande passante - mais je suis sûr que vous atteindrez d'abord la limite de lots). Cela ne se produira généralement que si vous avez un monde vraiment énorme - vous pouvez donc généralement vous contenter d'une élimination très simpliste, rapide mais imprécise dans ce cas.

Maintenant - Si vous dessinez avec suffisamment de permutations de texture pour dépasser la limite de lot, et que beaucoup d’entre elles sont en réalité hors écran et qu’elles seraient réduites à la limite. Alors oui - la sélection est une optimisation qui fonctionnera.

Cependant , une meilleure optimisation à poursuivre dans ce cas consiste à utiliser des atlas de texture (ou feuilles de sprite). Cela vous permet de réduire le nombre de textures échangées et donc les lots, indépendamment de ce qui est affiché à l'écran ou désactivé. (C’est la raison principale pour laquelle vous pouvez spécifier un rectangle source pour vos sprites.)


(Comme toujours: il s'agit d'un conseil sur l'optimisation des performances. Vous devez donc mesurer et comprendre les performances de votre jeu et les limites que vous rencontrez avant de vous efforcer d'optimiser.)

Andrew Russell
la source
5
+1 Il est important de ne pas choisir de cueillir uniquement pour des raisons de performance.
Will Marcouiller
12
+1 pour finalement me dire que les feuilles de sprite ont bien une raison d'exister autre que pour la commodité des programmeurs / concepteurs
Bill
3
+1 pour une bonne explication, j'ai beaucoup appris de votre réponse.
Jesse Emond
1
Le lien vers le fichier pdf "Lot, Lot, Lot" est rompu. En voici une mise à jour: ce.u-sys.org/Veranstaltungen/…
Marton
13

Selon un article sur les forums de MSDN, le framework XNA ne fait pas l’abattage aléatoire:

Le framework XNA ne fera pas de dépouillement inutile pour vous - il ne pourrait pas être car il n’a pas la moindre idée de la destination finale. Toutes les transformations sont effectuées sur le GPU et pourraient être un shader personnalisé.

http://xboxforums.create.msdn.com/forums/p/22763/121897.aspx

Ce post continue en disant que si vous avez beaucoup d'objets dans votre scène, cela peut valoir la peine de rouler le vôtre.

Nate
la source
6
Surtout si vous avez une carte à défilement (vous avez dit que c'était en 2D, donc cela pourrait être pertinent). Ce n'est qu'un gaspillage si vous dessinez de grandes sections inutiles. Ce n'est pas terriblement difficile et vous pourriez voir une sorte d'amélioration.
Michael Coleman
1

Je développe depuis quelques années des moteurs procéduraux voxel procéduraux sous XNA. Dans la plupart des cadres, les moteurs transforment littéralement des centaines de milliers de quads. Dans mon profilage, j'ai constaté que l'élimination du frustum et de l'occlusion améliorait les performances.

Le profil XNA HiDef (et non Reach) contient une classe OcclusionQuery qui est utilisée pour effectuer le retrait d’occlusion. Occlusion Culling supprime les quads d'une fenêtre masquée par d'autres quads.

Une autre chose que vous devriez considérer est la lecture de la génération et du tesselation séparément.

Donc, effectivement, lorsque vous approchez un très grand nombre de quadruples dans chaque image en cours de transformation, vous devez réfléchir à la manière dont vous pouvez appliquer des techniques de culling et de threading pour maintenir la cadence, en réduisant le trafic sur les gpu shaders.

Jason Coombes
la source