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

Kippstrahl

Frischling

  • »Kippstrahl« ist der Autor dieses Themas

Beiträge: 18

Wohnort: Kiel

Beruf: 12.JG

  • Private Nachricht senden

1

14.04.2011, 11:18

Frustum Culling

Hi, ich versuche gerade Minecraft in C++ nachzubauen, um meine Kenntnisse in DX zu verbessern.
Da die gesamte Szene nur aus Würfeln besteht, müsste es prinzipiell einfach sein, das Culling zu implementieren.
Meine Frage an dieser Stelle: Ist Frustum Culling ausreichend oder muss ich extra Octrees dafür verwenden bzw. gibt es eine bessere Methode?

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

2

14.04.2011, 11:31

Naja, da in Minecraft ja alles an einem regulären Gitter ausgerichtet ist wird es sich anbieten die ganze Welt in einem solchen abzulegen (also einfaches Array). Damit sollte Frustrum Culling sehr einfach und genau realisierbar sein, ein Octree wäre da nur unnötiger Overhead und würde vermutlich sogar bremsen.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

14.04.2011, 11:32

Nun, jeden Würfel einzeln zu cullen (und ich hoffe nicht, dass du Würfel/Flächen zeichnest, die im Inneren liegen und somit eh nicht sichtbar sind) dürfte fast mehr Performance fressen als sie einfach zu zeichnen. Daher ist zumindest eine Gruppierung definitiv sinnvoll, auch wenn es nicht unbedingt ein Octree sein muss.
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]

Kippstrahl

Frischling

  • »Kippstrahl« ist der Autor dieses Themas

Beiträge: 18

Wohnort: Kiel

Beruf: 12.JG

  • Private Nachricht senden

4

14.04.2011, 11:43

Nun, jeden Würfel einzeln zu cullen (und ich hoffe nicht, dass du Würfel/Flächen zeichnest, die im Inneren liegen und somit eh nicht sichtbar sind) dürfte fast mehr Performance fressen als sie einfach zu zeichnen. Daher ist zumindest eine Gruppierung definitiv sinnvoll, auch wenn es nicht unbedingt ein Octree sein muss.
Da habe ich mir überlegt, dass beim Generieren des "Terrains" überprüft wird, ob ein Würfel von 6 anderen umschlossen wird, und wenn ja, dass dieser dann gar nicht gezeichnet wird. Hierbei handelt es sich ja nicht um eine Überprüfung in der Echtzeit.

Eine zweite Frage: Das Culling der Innenseiten (also das, was man dank Clipping eh nicht sieht) muss ich nicht übernehmen oder? Denn ich habe mal gehört, dass man auch die Würfel einfach Face per Face zeichnet und von Anfang an nicht sichtbare Faces ausschließen kann.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

5

14.04.2011, 11:46

Culling macht nur auf Objektebene Sinn, wenn es nur Würfel sind vermutlich sogar nur (wie BlueCobold schon gesagt hat) auf Ebene von ganzen Brocken von Würfeln. Einzelne Dreiecke zu Cullen macht ganz sicher keinen Sinn da die CPU sehr viel länger brauchen würde um festzustellen ob ein einzelnes Dreieck gezeichnet werden muss oder nicht als die Grafikkarte braucht um 20 ganze Würfel zu malen ;)

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

14.04.2011, 13:03

Da habe ich mir überlegt, dass beim Generieren des "Terrains" überprüft wird, ob ein Würfel von 6 anderen umschlossen wird, und wenn ja, dass dieser dann gar nicht gezeichnet wird. Hierbei handelt es sich ja nicht um eine Überprüfung in der Echtzeit.

Man kann sogar einzelne Seiten der Würfel weglassen, welche an einen anderen angrenzen. Kann ja durchaus sein, dass von einem Würfel nur eine Seite sichtbar ist, ähnlich wie bei Kopfsteinpflaster auf einer Straße. Allerdings sollte die Geometrie dabei wirklich irgendwie gepuffert werden ohne diese Berechnung in jedem Frame zu machen, sonst verlierst Du mehr als Du gewinnst. Mit "statischen" VBOs ist das aber eine duchaus eine Überlegung wert.

Eine zweite Frage: Das Culling der Innenseiten (also das, was man dank Clipping eh nicht sieht) muss ich nicht übernehmen oder? Denn ich habe mal gehört, dass man auch die Würfel einfach Face per Face zeichnet und von Anfang an nicht sichtbare Faces ausschließen kann.

Backface-Culling meinst Du. Nein, lass das die GPU machen. Wenn du das selber machen willst, dann müsstest Du das nach jeder Kamera-Änderung prüfen und das bringt nur Einbußen.
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]

Kippstrahl

Frischling

  • »Kippstrahl« ist der Autor dieses Themas

Beiträge: 18

Wohnort: Kiel

Beruf: 12.JG

  • Private Nachricht senden

7

16.04.2011, 16:09

Man kann sogar einzelne Seiten der Würfel weglassen, welche an einen anderen angrenzen. Kann ja durchaus sein, dass von einem Würfel nur eine Seite sichtbar ist, ähnlich wie bei Kopfsteinpflaster auf einer Straße.
Bisher habe ich alle im Frustum liegenden Würfel gerendert und dabei auf die Funktion Mesh->DrawSubset(0); zurückgegriffen. Diese Funktion rendert ja den gesamten Mesh. Wie kann ich nun aus diesem Mesh bestimmte Faces rauslassen?

Erstmal wird natürlich geprüft, ob und - wenn ja - wo der Würfel umschlossen wird. Sagen wir ich habe das Face ermittelt. Ich stelle mir das beim Rendern jetzt problematisch vor, da ich ja jetzt diese Faces aus dem Rendern ausschließen muss. Ich glaube, in Echtzeit die Faces aus dem Mesh herauszunehmen wäre keine gute Idee. Eine weitere Möglichkeit wäre, dass jedes Würfel-Objekt (was bei mir so noch nicht existiert) einen Mesh besitzt, der beim Erstellen des Terrains modifiziert wird. Dies würde natürlich erheblich mehr Speicheraufwand bedeuten.

Vielleicht wäre es sinnvoll, auf Vertexbuffer statt Meshes zurückzugreifen, da es sich um sehr simple Modelle handelt?

8

16.04.2011, 16:57

Die Meshklasse wird intern VertexBuffer benutzen. Ich benutze DX zwar eine ganze Weile schon nicht mehr, aber alles andere würde keinen Sinn machen.

Du solltest zusehen, dass du die Optimierungen nicht in jedem Frame neu berechnest. Zusätzlich solltest du dir Gedanken darüber machen, dass die Kommunikation mit der Grafikkarte teuer ist, also immer möglichst viel in einem Rutsch rendern. Es ist weitaus billiger 100 Würfel auf einmal so rendern, als 10 Würfel für Würfel (die Dimensionen müssen nicht genau stimmen und hängen auch von sehr vielen Faktoren ab, aber so ungefähr verhält es sich).
Ich würde dir empfehlen, Große teile des Levels zu einem Vertexbuffer zusammen zu legen. Dabei kannst du dann gleich im inneren liegende Würfel weglassen und auch nur die Seite dabeipacken, die man wirklich sieht. Die Vertexbuffer musst du natürlich aktualisieren, sobald sich was im Level ändert, aber das passiert ja nur ab und zu (im Bezug auf die Framezahl), also ist das ganz egal. Ist natürlich mehr Aufwand, sollte die Sache aber erheblich schneller machen.

Letztendlich musst du wissen, was du willst. Man kann vermutlich mittelgroße Levels auch ohne Optimierungen flüssig rendern, aber wenn du was lernen willst, macht es ja durchaus Sinn, das ganze mal zu optimieren.
Lieber dumm fragen, als dumm bleiben!

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

9

17.04.2011, 09:02

Jup. Einmal 100 Würfel zu rendern ist deutlich schneller als hundert mal einen einzelnen.
Da wirst Du vermutlich ähnlich viel Performance rausholen wie Du mit Deinem Frustum-Culling erreichen willst. Eine Umstellung Deiner gesamten Geometrie wäre also von Vorteil.
Wie Jonathan sagte wäre es vermutlich klug, große Teile des Levels (die Du dann separat cullen kannst) in einem VBO abzulegen statt jeden Würfel einzeln.
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]

Kippstrahl

Frischling

  • »Kippstrahl« ist der Autor dieses Themas

Beiträge: 18

Wohnort: Kiel

Beruf: 12.JG

  • Private Nachricht senden

10

17.04.2011, 20:51

Jup. Einmal 100 Würfel zu rendern ist deutlich schneller als hundert mal einen einzelnen.
Da wirst Du vermutlich ähnlich viel Performance rausholen wie Du mit Deinem Frustum-Culling erreichen willst. Eine Umstellung Deiner gesamten Geometrie wäre also von Vorteil.
Wie Jonathan sagte wäre es vermutlich klug, große Teile des Levels (die Du dann separat cullen kannst) in einem VBO abzulegen statt jeden Würfel einzeln.
Ja, dass die Würfel-für-Würfel Methode ineffizient ist, war mir durchaus bewusst, ich wollte es erstmal nur zum Laufen bringen. Ich habe das Gitter nochmal in Chunks (16 x 16 x 128) unterteilt (so wie es das Original macht), sodass ich dann Chunk für Chunk rendere, also für jeden Chunk einen VertexBuffer anlege.

Werbeanzeige

Ähnliche Themen