Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Toemsel

Treue Seele

  • »Toemsel« ist der Autor dieses Themas

Beiträge: 310

Wohnort: OÖ

Beruf: Student und Programmierer

  • Private Nachricht senden

1

08.03.2016, 08:12

Tilemaps rendern

Für mein aktuelles Projekt muss ich eine Tilemap rendern. An sich kein Problem, nur mache ich mir Sorgen um die Performance.
Die Tilemap beschrenkt sich nicht auf den aktuellen ViewPort, sondern überstreckt sich (theoretisch) endlich in beide Richtungen.
Mithilfe von sehr simplen Algorithmen kann ich nur die Tiles rendern, welche sich auf im ViewPort befinden.
Jedoch möchte ich so wenig Performance wie nur möglich verlieren.

Ich dachte an zwei Optionen.
1. Tile für Tile pro Draw Aufruf rendern
2. Mehrere (x-beliebige) Tiles in eine neue, größere Textur rendern (einmalig) und anschließend immer die zusammengefasste Version zeichnen.
Gerne würde ich die 2. Version in Erwägung ziehen, jedoch sind RenderTargets auf 10MB beschränkt, der VRAM kostbar und ich bin mir unsicher wie schnell größere Texturen swappen.
Gibt es eine "Magic number" welche sich mit Grafikkarten allgemein gut versteht? (Mal davon abgesehen das sie ein Vielfaches von 2 sein sollte :P )
Es sollte eine gute Mischung aus Größe und Menge sein. Aufgrund meiner Horsepower auf meinem PC kann ich hier keine fairen Benchmarks durchführen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

08.03.2016, 08:31

Fass einfach mehrere Tiles zu einem Block zusammen. Z.B. ein Viertel der Screengröße. Diese kannst Du separat auf Sichtbarkeit testen. Jedes Tile einzeln zu zeichnen und auch jedes Tile einzeln auf Sichtbarkeit zu testen, ist jedenfalls nicht optimal. Eventuell reicht es auch alles in einen einzigen VertexBuffer zu schmeißen und diesen komplett ohne Sichtbarkeits-Prüfung vollständig zu rendern und den Rest der Grafikkarte zu überlassen.
Ich würde nicht unbedingt dazu raten die Dinger in einer Textur vorzurendern. Das gibt meist Probleme mit diversen z-Überlappungen von dynamischen Objekten.
Allerdings muss ich auch erwähnen, dass solche Optimierungen heutzutage selbst auf Smartphones eventuell komplett überflüssig sind. Man verbrät Leistung, klar. Aber man spart an Entwicklungsaufwand ;)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

3

08.03.2016, 10:03

Eine ganze Gruppe von Tiles pro Draw Call zu rendern ist wohl der beste Ansatz. Einfach alles zu rendern wird, abhängig von der Größe der Map, doch recht schnell recht verschwenderisch. Wenn es sich speichermäßig ausgeht, könntest du die ganze Map z.B. einfach zeilenweise in einen Vertex und Index Buffer zu packen. Dann brauchst du in jedem Frame nur ausrechnen, welche Abschnitte welcher Zeilen sichtbar sind und dann machst du einen Draw Call pro Zeile...

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

4

08.03.2016, 11:42

Tiles sind regelmäßig geordnet. Du kannst also jederzeit exakt bestimmen, welche Tiles sichtbar sind, *ohne* die einzelnen Tiles abzuklappern. Von da an ist es kein Problem mehr, einfach alle sichtbaren Tiles auf einen Rutsch rauszuhauen. Das ist der komplett dynamische Ansatz, den ich üblicherweise fahre, und quasi jedes Framework bringt irgendne Art Sprite Batcher mit, um mit dieser Arbeitsmethode schnell ans Ziel zu kommen. Noch schneller wird's, wenn die Tiles dann auf einem Texturatlas zusammengefasst werden.

dot's Idee der VertexBuffer-Ausschnitte geht aber auch prima, weil die Tiles ja linear darin liegen und Du nur einen linearen Ausschnitt daraus brauchst. Dann kannst Du schlicht über die DrawCall-Parameter bestimmen, welchen Zeilenabschnitt Du brauchst. Dafür musst Du minecraft-style alle Buffer, die von einer Änderung betroffen sind, neu erstellen. "So effizient" wie möglich wär das nicht, weil Du bei kleinsten Änderungen jeweils ganze Zeilen neu erstellen musst, was bei großen Maps ein enormes Missverhältnis zwischen Änderungen und statischen Daten wäre. Die offensichtliche Verbesserung wäre das Organisieren in Quadraten anstatt in Zeilen, weil in nem Quadrat räumlich alles näher beieinander liegt und demzufolge wahrscheinlicher ebenso von einer Änderung betroffen wäre. Und das trotzdem noch mit dot's Idee der DrawCall-Parameter zu rendern wär ne richtig geile Spielerei. Du kannst ja in nem 2D-Gebilde jeweils eine Zeile rendern und dann per Instancing und mit Offset pro Instanz den Differenz zur nächsten Zeile umsetzen. Hey, das wär cool.

Leider ist das, wie BlueCobold schon schrieb, völlige Verschwendung von Lebenszeit, weil selbst Handys stressfrei jede Zelda-Map in einem DrawCall raushauen und dabei noch nichtmal aus der Puste geraten. Aber wenn Du das als Hobby betreibst, warum nicht... es gibt da doch Ansätze, die ich zu Lebzeiten noch nicht gesehen habe :-)
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

08.03.2016, 11:50

Letztlich hängt es auch stark vom Ziel ab. Also über was reden wir hier? Reden wir von 1000x1000 Tiles, von denen immer nur 20x15 auf den Bildschirm passen? Oder von 1000x1000, wovon immer 800x600 zu sehen sind (in Zeiten von 4k-Monitoren muss man selbst mit sowas ja eventuell rechnen)? Oder reden wir von 100x80, von denen 80x60 auf den Bildschirm passen? Oder von 12x8 Tiles, von denen 10x6 auf den Screen passen? Das macht plötzlich riesige Unterschiede. daher bezog ich mich bei meiner Gruppierung auf eine Menge an Tiles, abhängig von der Darstellungsmenge.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

6

08.03.2016, 12:18

Für unendlich große Tilemaps nehme ich immer Chunks, ähnlich wie in Minecraft, werden dabei z.B. 10x10 Tiles zu einem Buffer zusammengefasst und dieser wird auf Sichtbarkeit geprüft. Wenn sich der Spieler bewegt können (wenn wirklich so riesig ist) dann dynamisch neue Buffer erzeugt werden und am "anderen Ende" wieder freigegeben werden.
Man kann aber auch sehr sehr große Karten einfach in einem Buffer rendern. So wirklich spüren wird man das zumindest auf einem PC wahrscheinlich nicht.

Toemsel

Treue Seele

  • »Toemsel« ist der Autor dieses Themas

Beiträge: 310

Wohnort: OÖ

Beruf: Student und Programmierer

  • Private Nachricht senden

7

09.03.2016, 09:54

Vielen Dank für den Input. Ich werde das ganze mal in einen VertexBuffer packen und schaun wie sich das ganze verhält.
Werde noch etwas recherchieren müssen, ob MonoGame hier selbst bereits ViewPort Optimierungen bewerkstelligt, oder ob ich hier selbst noch Hand anlegen muss.

Aktuell bin ich mir über die Tilegröße noch unsicher. Auflösung ist statisch mit 1366x768 festgelegt. Alles darüber und darunter wird skaliert und bei bedarf in eine LetterBox gepackt.
(Möchte einem 4K User keinen Vorteil gegenüber einem HD User ermöglichen) Theoretisch würde somit die Anzahl der Tiles (bei 1x1px) bei 1.049.088 liegen. Tendiere jedoch zu 32x32px (32784 tiles).

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

8

09.03.2016, 10:00

Wichtiger als die Anzahl der dargestellten Tiles ist die Anzahl der nicht sichtbaren Tiles ;) Sind nämlich nur 20% nicht sichtbar, ist das was ganz anderes als wenn 95% nicht sichtbar sind. Bei ersterem lohnt sich View-Culling überhaupt nicht.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Toemsel

Treue Seele

  • »Toemsel« ist der Autor dieses Themas

Beiträge: 310

Wohnort: OÖ

Beruf: Student und Programmierer

  • Private Nachricht senden

9

09.03.2016, 17:16

Endlich in beide Richtungen. Praktisch eine offene Karte

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

10

09.03.2016, 18:35

Lies meinen Beitrag nochmal. :)
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Werbeanzeige