Wie kann der Spieler die Blöcke sehen?


15

Ich schreibe ein Minecraft-ähnliches Spiel mit der Ogre-Engine und habe ein Problem. Ich muss mein Spiel optimieren, denn wenn ich versuche, 10000 Blöcke zu zeichnen, habe ich 2 FPS ... Also kam mir die Idee, dass Blöcke die Ebene anzeigen und die unsichtbaren Blöcke verbergen. Aber ich habe ein Problem - woher weiß ich, welche Blöcke gleichzeitig für den Player sichtbar sind?

Und - wenn Sie andere Optimierungsmethoden für ein solches Spiel kennen, schreiben Sie, was und wie Sie sie in Ogre verwenden.

Antworten:


16

Nun, Ogre implementiert bereits das Kegelstumpf-Keulen (das im Grunde genommen nichts zeichnet, was von der Kamera nicht gesehen werden kann), aber ich denke, Ihr Problem ist ein anderes.

Sie sollten nicht wirklich 10000 Blöcke anzeigen, was häufig gemacht wird (oder zumindest in den wenigen Ogre3d-basierten Minecraft-Klonen, die ich gesehen habe (von denen ich auch einen erstelle) und im Original), ist das Erstellen eines Netzes ( einer NxNxN-Region von Brocken), die die Außenflächen der gezeigten Würfel aufweist. Das heißt, wenn Sie zwei Würfel nebeneinander legen, sind die beiden sich berührenden Flächen nicht sichtbar und müssen daher nicht gezeichnet werden.

Diese Flächen sollten auch in etwa so gezeichnet sein: http://www.ogre3d.org/tikiwiki/tiki-index.php?page=DynamicGrowingBuffers, da moderne Grafikkarten eine Masche mit 100000 Polygonen gegenüber 1000 Maschen mit 100 Polygonen bevorzugen.


10

Dieses Problem hat einige Aspekte. Erstens, wie zeichnest du deine 10000 Blöcke? Zeichnen Sie sie tatsächlich als 10000 separates Objekt? Wenn ja, ist dies mit ziemlicher Sicherheit Ihr Flaschenhals, nicht die fehlende Okklusionsentfernung. Sie sollten diese Blöcke in eine kleinere Anzahl von Maschen gruppieren (möglicherweise einige Tausend pro Masche), um Draw Calls zu reduzieren.

Was Ihre eigentliche Frage betrifft, so gibt es drei Arten von Okklusions-Culling, die in den Sinn kommen.

1) Blöcke außerhalb des Sichtstumpfes. Dies bedeutet Blöcke, die sich hinter Ihnen oder zwei an der Seite befinden. Ogre entfernt diese bereits über das View-Frustum-Culling.

2) Blöcke, die unterirdisch oder vollständig von anderen Blöcken umgeben sind, so dass sie aus keinem Winkel gesehen werden können. Sie können diese identifizieren, indem Sie sich die benachbarten Blöcke ansehen. Wenn sie alle fest sind, ist dein Block verborgen. Die GPU sollte nie etwas von diesen Blöcken hören - sie sollten übersprungen werden, wenn Sie das Netz erstellen, das Ihre Oberfläche darstellt.

3) Blöcke, die sich auf der Oberfläche befinden und von einigen Positionen im Level aus zu sehen sind, die derzeit jedoch von einem Hügel (oder etwas anderem) verborgen werden. Dies ist der schwierigste Fall, den ich selbst nicht angesprochen habe, aber es besteht eine gute Chance, dass für diesen Fall Hardware-Okklusionsabfragen verwendet werden können.

Es ist ein schamloser Plug, aber ich habe eine ziemlich ausgereifte Bibliothek, mit der mehrere Leute Minecraft-Klone entwickeln, darunter auch einige mit Ogre. Sie definieren den Inhalt des Volumens und es generiert das Oberflächennetz, das Sie dann rendern können. Hier ist die Homepage:

http://www.thermite3d.org/

Und hier ist ein Video von einem anderen Projekt, das es verwendet:

http://www.youtube.com/watch?v=Jju6WRPEK7o


4

Sie können Backface-Culling verwenden, um Scheitelpunkte und die dazugehörigen Pixel zu entfernen, die nicht zum Player zeigen. Die Tiefenpufferung sollte den Rest erledigen. 10k Blöcke sind wirklich nicht viel, meine 5770 kann 100k Verts bei 1500fps rendern. Ich denke, dass Sie etwas anderes ziemlich falsch machen.


Genau. Dies ist wahrscheinlich ein Problem mit irgendetwas anderem.
Notabene

1

Wenn Sie 10000 separate Objekte haben, handelt es sich wahrscheinlich um eine primitive Anzahl, nicht um einen Scheitelpunkt, ein Polygon oder eine Füllung. Backen Sie Ihre Objekte aus Gründen der Geschwindigkeit in eine kleinere Anzahl von Objekten mit höherem Polygon.

Minecraft hat ein Konzept von Würfelblöcken, aber ich kann die Referenz im Moment nicht finden.

Hier sind auch meine Experimente zum Zeichnen von Tonnen von Würfeln mit verschiedenen Techniken. Backen (noch) nicht inbegriffen.


0

Nachdem ich mein Array von Blöcken erstellt habe, aber bevor ich die Scheitelpunkte erstelle, führe ich ein Sub mit dem Namen UpdateBlockVisiblility aus.

Das Sub überprüft einfach die Nachbarn des Blocks und aktualisiert den Facevisible-Booleschen Wert des Blocks entsprechend.

#define BLOCKFACE_NORTH 0

#define BLOCKFACE_SOUTH 1 

etc etc etc

if(IsBlockAt(NorthOfBlock))
  Blocks[Whatever].facevisible[BLOCKFACE_NORTH] = false;

Dann erstelle ich die Eckpunkte für das Gesicht, wenn es sichtbar ist! Einfach :)

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.