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:
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?
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:
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.
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:
Tags und Links java c++ geometry computational-geometry