Ich habe viele Beispiele für das Rendern von Sprites aus einem Spritesheet gesehen, aber ich habe nicht verstanden, warum dies die häufigste Art ist, mit Sprites in 2D-Spielen umzugehen.
Ich habe in den wenigen Demo-Anwendungen, die ich erstellt habe, mit dem Rendern von 2d-Sprites begonnen, indem ich jeden Animationsrahmen für einen bestimmten Sprite-Typ als eigene Textur behandelt habe - und diese Sammlung von Texturen wird in einem Wörterbuch gespeichert. Dies scheint für mich zu funktionieren und passt ziemlich gut zu meinem Arbeitsablauf, da ich meine Animationen in der Regel als GIF- / MNG-Dateien erstelle und dann die Frames in einzelne PNGs extrahiere.
Gibt es einen spürbaren Leistungsvorteil beim Rendern von einem einzelnen Blatt anstatt von einzelnen Texturen? Ist es bei moderner Hardware, die in der Lage ist, Millionen von Polygonen hundertmal pro Sekunde auf den Bildschirm zu ziehen, sogar für meine 2D-Spiele von Bedeutung, die nur ein paar Dutzend Rechtecke mit einer Auflösung von 50 x 100 Pixel verarbeiten?
Die Implementierungsdetails zum Laden einer Textur in den Grafikspeicher und zum Anzeigen in XNA scheinen ziemlich abstrakt zu sein. Ich weiß nur, dass Texturen beim Laden an das Grafikgerät gebunden werden. Während der Spieleschleife werden die Texturen stapelweise gerendert. Daher ist mir nicht klar, ob meine Wahl die Leistung beeinflusst.
Ich vermute, dass es einige sehr gute Gründe gibt, warum die meisten 2D-Spieleentwickler sie zu verwenden scheinen. Ich verstehe nur nicht, warum.
quelle
Antworten:
Ein starkes Argument für die Verwendung von Spritesheets ist, dass die Anzahl der verfügbaren Texturen auf einer Grafikkarte begrenzt werden kann. Daher müsste Ihre Grafikbibliothek ständig Texturen entfernen und Texturen auf der GPU neu zuweisen. Es ist viel effizienter, eine große Textur nur einmal zuzuweisen.
Berücksichtigen Sie außerdem, dass die Texturgröße normalerweise Potenz 2 ist. Wenn Sie also ein Sprite mit 50 x 100 Pixel haben, weisen Sie Texturen mit der Größe 64 x 128 Pixel oder im schlimmsten Fall 128 x 128 Pixel zu. Das verschwendet nur Grafikspeicher. Packen Sie besser alle Sprites in eine 1024x1024px-Textur, die 20x10 Sprites zulässt, und Sie verlieren nur 24 Pixel horizontal und vertikal. Manchmal werden sogar Sprites unterschiedlicher Größe zu einem riesigen Sprite-Sheet kombiniert, um die Textur so effizient wie möglich zu nutzen.
Nachtrag: Ein sehr wichtiger Grund für die Verwendung von Sprite-Sheets besteht darin, die Anzahl der Zugriffe auf Ihre GPU zu verringern, was sich erheblich auf die Leistung auswirken kann. Dies wurde in anderen Antworten angegeben und ich füge dies der Vollständigkeit halber hinzu, damit dies etwas sichtbarer wird.
quelle
Ich würde sagen, das Argument wäre die Fähigkeit, mehrere Dinge in einem einzigen Draw-Aufruf zu rendern. Nehmen wir zum Beispiel das Rendern von Schriften, ohne ein Spritesheet müssten Sie jedes Zeichen mit einem separaten Texturtausch rendern, gefolgt von einem Zeichenaufruf. Wenn Sie sie in ein Spritesheet werfen, können Sie mit einem einzigen Zeichenaufruf ganze Sätze rendern (wobei die unterschiedlichen Zeichen in der Schriftart nur durch Angabe der verschiedenen UV-Werte für die Ecken ermittelt werden). Dies ist eine viel effizientere Methode zum Rendern, wenn der Aufwand für das Rendern von Inhalten auf vielen Plattformen darin besteht, zu viele API-Aufrufe zu tätigen.
Es kann auch helfen, Platz zu sparen, aber es hängt davon ab, was Sie zuerst in das Spritesheet packen.
quelle
Jeder Draw Call hat einen gewissen Overhead. Mit Sprite-Arbeitsblättern können Sie die Zeichnung von Dingen stapeln, die nicht den gleichen Frame einer Animation verwenden (oder allgemeiner, alles, was sich auf demselben Material befindet), um die Leistung erheblich zu verbessern. Für moderne PCs ist dies abhängig von Ihrem Spiel vielleicht nicht allzu wichtig, aber es ist definitiv wichtig, zum Beispiel für das iPhone.
quelle
Neben Überlegungen zur Leistung können Sprite-Blätter beim Erstellen der Grafik hilfreich sein. Jedes Zeichen kann sich auf einem eigenen Blatt befinden, und Sie können alle Frames anzeigen, indem Sie einfach einen Bildlauf durchführen. Es hilft mir, einen konsistenten Überblick über alle Frames zu behalten.
Außerdem codiere ich in AS3, und für jede Bilddatei ist eine separate Einbettungsanweisung erforderlich. Ich hätte lieber eine einzelne Einbettung eines gesamten Spritesheets als 24 Einbettungen für alle Frames, selbst wenn ich eine separate Ressourcenklasse verwende.
quelle
Ein weiterer Grund für die Verwendung von Spritesheets mit XNA ist, dass bei der Xbox360-Entwicklung ein bekanntes Problem mit langsamen Bereitstellungs- / Ladezeiten im Verhältnis zur Anzahl der Dateien in Ihrem Projekt besteht. Wenn Sie also viele kleine Bilddateien zu einer einzigen Bilddatei kombinieren, können Sie dieses Problem lösen.
quelle
Ich werde hier nicht auf Speicher / GPU eingehen, da es so genug Antworten gibt.
Stattdessen kann es Ihre Kunst aufklären, während Sie daran arbeiten - und danach. Anstatt 10 Bilder durchzublättern, um den Laufzyklus zu sehen, können Sie alle Bilder auf einmal sehen. Wenn Sie dies verteilen möchten, müssen Sie statt 10 nur noch 1 Datei bearbeiten.
Und dann ist es auch sauberer (aus organisatorischer Sicht), character.png und enemy.png über characterwalk01 bis characterwalk10, dann characterattack01 bis characterattack05 zu haben, und es geht weiter.
quelle
Der Grafikspeicher verfügt nicht über eine aufgeblähte Speicherverwaltung wie Dateisysteme auf Datenträgern. Das Gegenteil ist der Fall: Es ist einfach und schnell gehalten .
Eine solche einfache und schnelle Speicherverwaltung könnte so aussehen, als hätte man nur ein einziges riesiges 4096x4096-Sprite, das durch Halbieren seiner Breite und / oder Höhe in mehrere kleinere Sprites geschnitten wird. (Es gibt eine ähnliche 1-dimensionale Speicherverwaltungstechnik, aber ich habe den Namen vergessen.) Schließlich muss eine Defragmentierung durchgeführt werden.
Um eine solche Speicherverwaltung zur Laufzeit zu überspringen , füllen Entwickler einzelne große Sprites beim Kompilieren oder sogar während des Designprozesses der Grafiken automatisch mit mehreren kleineren Sprites .
quelle
Vergessen Sie auch nicht die E / A-Vorgänge, die Sie möglicherweise während der Initialisierung sparen. Wenn Sie von einem CD-Laufwerk laden, handelt es sich bei jeder Datei um einen zusätzlichen E / A-Aufruf. Die Suche kann einige Zeit in Anspruch nehmen (moderne Festplatten haben eine Länge von etwa 15 ms pro Datei, CDs von etwa 50 bis 100 ms?). Dies kann Ihnen viel Initialisierungszeit sparen, da nur eine Datei abgerufen werden muss. Außerdem kann Ihr Betriebssystem diese E / A-Vorgänge zwischenspeichern, falls Ihre Anwendung etwas anderes ausführt (z. B. auf die GPU warten).
quelle
Ich bin nicht nur leistungsfähiger, sondern finde es auch einfacher. Es erfordert ein wenig zusätzliche Arbeit, um sicherzustellen, dass Ihre Bilder beim Erstellen der Grafik immer innerhalb ihrer Grenzen bleiben. Es ist jedoch viel einfacher, alle Bilder zu sehen, mit denen Sie sich gerade beschäftigen.
Es ist meiner Meinung nach auch einfacher zu codieren. Ich habe einfach eine Reihe von Objekten wie:
Dann gebe ich für jedes Item zwei Werte, sheet und rect. Das Blatt wäre der Index in dem Array von Objekten und das Rect wäre der Index in dem Rect-Array dieses Blatts.
quelle