3D Spiel Geometrie

8

Ich habe ein einfaches Spiel, das eine 3D-Gitterdarstellung verwendet, etwa wie folgt:

%Vor%

Die Person im Spiel wird durch einen Punkt und einen Sichtvektor dargestellt:

%Vor%

Ich zeichne das Gitter mit 3 verschachtelten For-Schleifen:

%Vor%

Das offensichtliche Problem dabei ist, wenn die Größe des Gitters innerhalb der Hunderter wächst, fps dramatisch fallen. Mit etwas Intuition erkannte ich das:

  • Blöcke, die von anderen Blöcken im Gitter verborgen wurden, müssen nicht gerendert werden
  • Blöcke, die nicht im Sichtfeld der Person waren, müssen auch nicht gerendert werden (dh Blöcke, die hinter der Person waren)

Meine Frage ist, ob ein grid[][][] , eine x,y,z einer Person und ein Sehvektor dx,dy,dz , wie könnte ich herausfinden, welche Blöcke gerendert werden müssen und welche nicht?

    
Andrew Liu 16.02.2012, 03:00
quelle

3 Antworten

7

Ich habe mit JMonkeyEngine , einer 3D-Spielengine, vor einiger Zeit nachgeschaut und mir einige Techniken angesehen, die sie einsetzen. Soweit ich mich erinnere, benutzen sie etwas, das man Keulung nennt. Sie bauen eine Baumstruktur von allem auf, was in der "Welt" existiert. Die Idee ist dann, dass Sie eine Teilmenge dieses Baumes haben, die die sichtbaren Objekte zu jeder gegebenen Zeit darstellt. Mit anderen Worten, das sind die Dinge, die gerendert werden müssen. Sagen Sie zum Beispiel, dass ich ein Zimmer mit Objekten im Raum habe. Der Raum ist auf dem Baum und die Objekte im Raum sind Kinder des Baumes. Wenn ich außerhalb des Raumes bin, dann beschneide ich diesen Zweig des Baumes, was bedeutet, dass ich ihn nicht rende. Der Grund, warum dies so gut funktioniert, ist, dass ich JEDES Objekt in der Welt nicht evaluieren muss, um zu sehen, ob es gerendert werden sollte, sondern stattdessen ganze Teile der Welt, die ich nicht wiedergeben sollte >

Noch besser, wenn ich dann in den Raum gehe, trimme ich den Rest der Welt vom Baum und gebe nur den Raum und all seine Nachkommen wieder.

Ich denke, viele der Designentscheidungen, die das JMonkeyEngine-Team getroffen hat, basierten auf den Dingen in David Eberlys Buch 3D Spiel Engine Design . Ich kenne die technischen Details nicht, um einen solchen Ansatz zu implementieren, aber ich wette, dieses Buch wäre ein guter Ausgangspunkt für Sie.

Hier ist eine interessante Artikel zu verschiedenen Algorithmen zum Aussortieren:

  • Ansicht Frustum Culling
  • Rückseiten-Culling
  • Zellbasiertes Okklusionsculling
  • PVS-basierte willkürliche Geometrie Okklusions-Culling
  • Andere
jbranchaud 16.02.2012, 03:18
quelle
1

Zuerst benötigen Sie eine räumliche Partitionierungsstruktur. Wenn Sie einheitliche Blockgrößen verwenden, ist wahrscheinlich die effektivste Struktur ein Octree . Dann müssen Sie einen Algorithmus schreiben, der berechnen kann, ob sich eine Box auf einer bestimmten Seite einer Ebene befindet (oder sich schneidet). Sobald Sie das haben, können Sie herausfinden, welche Blattknoten des Octrees sich innerhalb der sechs Seiten Ihres View-Frustums befinden - das ist view culling . Mit dem Octree können Sie auch bestimmen, welche Blöcke andere blockieren (manchmal frustum masking genannt), aber zuerst den ersten Teil bearbeiten.

    
cmannett85 16.02.2012 13:58
quelle
1

Es hört sich so an, als würdest du nach einem minecraft-y-artigen Ding suchen. Werfen Sie einen Blick auf dieses Android-Minecraft-Level Renderer . Die zu beachtenden Punkte sind:

  • Sie müssen nur die Gesichter von Blöcken zeichnen, die mit transparenten Blöcken geteilt werden. z. B. nicht die Gesichter zwischen zwei undurchsichtigen Blöcken zeichnen - der Spieler wird sie nie sehen.
  • Sie werden wahrscheinlich Ihre sichtbare Blockgeometrie in Chunklets aufteilen (und in eine VBO stecken) und die Sichtbarkeit pro Chunklet-Basis bestimmen. Das Auffinden von genau welche Blöcke zu sehen sind, wird wahrscheinlich länger dauern, als nur den VBO auf der GPU zu schleudern und die Überziehung zu akzeptieren.
  • Ein flood-fill funktioniert ziemlich gut, um zu bestimmen, welche Chunklets sichtbar sind - Begrenzen Sie die Füllung mit dem View-Frustum, Blickrichtung (wenn Sie in die + ve-Richtung schauen, fluten Sie nicht in der -ve-Richtung) und einfache Analysen von Chunklet-Daten (zB: wenn eine ganze Seite eines Chunklets undurchsichtig ist, fluten Sie nicht durch dieses Gesicht)
ryanm 18.02.2012 05:37
quelle