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

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

11

17.04.2011, 21:42

Na das is doch schon mal was. in diesen VBOs kannst du nun die Flächen eliminieren, die eh "innerhalb" liegen und nie sichtbar sein können. Dann noch Culling und fertig.
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

12

23.04.2011, 18:06

Ich bin dabei jetzt auf ein Problem gestoßen.
Zuerst habe ich für jeden Chunk einen gleich großen VertexBuffer erstellt (der bei nicht gezeichneten Würfelseiten einfach 0 als Wert hat). Da das jedoch total perfomancelastig ist (was ich später auch gemerkt habe), habe ich es folgendermaßen realisiert: Die Größe des VertexBuffers wird zur Laufzeit bestimmt (also nach dem Erstellen des Chunk). Problem ist, dass das Zeichnen dieser VertexBuffer total langsam ist, erstaunlicherweise viel langsamer als Würfel für Würfel.

Der VertexBuffer hat so viele Vertices, wie viele sichtbare Seiten der Chunk hat, multipliziert mit 6 (damit eine ganze Seite dabei herauskommt).

Wenn ich jetzt in dem Gitter 9 Chunks habe, die jeweils einen VertexBuffer haben, sind das ja 9 VertexBuffer, die ich zeichne.
Komischerweise ist das total langsam und ich weiß nicht wieso. Ich habe versucht das Problem so genau wie möglich zu schildern, weil der Source ziemlich groß ist und zu viele überflüssige Informationen enthalten würde, die für die Lösung des Problems nicht hilfreich wären.

Jedenfalls: Ist das Konzept, was ich hier beschreibe, richtig? Eigentlich dürfte es ja gar kein Problem sein, 9 VB's zu Rendern.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

13

23.04.2011, 19:01

Problem ist, dass das Zeichnen dieser VertexBuffer total langsam ist, erstaunlicherweise viel langsamer als Würfel für Würfel.

Dann machst du irgendwas falsch. Werden die Buffer in jedem Frame dynamisch befüllt? Für optimale Performance solltest du außerdem indizierte Primitive rendern, wirst also auch noch einen IndexBuffer brauchen.

Kippstrahl

Frischling

  • »Kippstrahl« ist der Autor dieses Themas

Beiträge: 18

Wohnort: Kiel

Beruf: 12.JG

  • Private Nachricht senden

14

24.04.2011, 11:43

Dann machst du irgendwas falsch. Werden die Buffer in jedem Frame dynamisch befüllt?
Nein, bei der Generierung des Gitters mit 4 x 4 Chunks (Ein Chunk = 16 x 16 x 128 Würfel) wird der VertexBuffer gefüllt (jede Instanz der Struktur SChunk hat einen VertexBuffer).

Nach dem ausschließen der nicht sichtbaren Seiten werden theoretisch

16*16*6*2 (für oben und unten)
+
16*16*128*4 (Außenseiten) Vertices in den Buffer geladen [134144 Gesamt]. Dürfte ja eigentlich kein Problem sein für die Grafikkarte. Mir ist durchaus klar, dass wenn ich 16 * 134144 Vertices versuche zu rendern, die Performance in den Keller geht (da das Culling hier noch nicht implementiert ist), jedoch bricht die Performance bereits bei einem einzigen Chunk ein.

Hier nochmal ein paar Ausschnitte:

Aus der Erstellung der Umgebung

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//...
#define VERTS_PER_CHUNK     CHUNK_SIZEXZ*CHUNK_SIZEXZ*CHUNK_SIZEY*6*6
//...

//Vertices erstellen
MGVertex::PositionTextured *verts = new MGVertex::PositionTextured[VERTS_PER_CHUNK];
ZeroMemory(verts, VERTS_PER_CHUNK);
pch->VBuffer.CreateBuffer(m_MGraphics->GetDevice(), VERTS_PER_CHUNK, D3DFVF_XYZ | D3DFVF_TEX1, sizeof(MGVertex::PositionTextured));

//...

//Hier ein Beispiel des Ausschließens der Seite (wenn Seite ausgeschlossen wird, wird der Buffer hier nicht beschrieben)
//Obere Seite
if(y == 0 || (y != 0 && pch->ChunkArray[x][z][y-1] == 0))
{
    verts[0+c*36]  = MGVertex::PositionTextured(...);
    verts[1+c*36]  = MGVertex::PositionTextured(...);
    verts[2+c*36]  = MGVertex::PositionTextured(...);
    verts[3+c*36]  = MGVertex::PositionTextured(...);
    verts[4+c*36]  = MGVertex::PositionTextured(...);
    verts[5+c*36]  = MGVertex::PositionTextured(...);
}

//...

pch->VBuffer.SetData(VERTS_PER_CHUNK, verts);   //Anzahl Vertices, Buffer

delete[] verts;



Und die Renderschleife:

C-/C++-Quelltext

1
2
3
4
5
//...
m_MGraphics.GetDevice()->SetTexture(0, m_pDirt);
//device, num primitives, primitivetype
chunk->VBuffer.Render(m_MGraphics.GetDevice(), (UINT)chunk->VBuffer.GetNumVertices()/3, D3DPT_TRIANGLELIST);
//...



Edit: Ich merke gerade, dass ich aus Versehen 4 Chunks gleichzeitig zeichne und nicht nur einen. Mein Counter zeigt mir 4'718'592 Gesamt-Vertices an. Bei der Zahl ist es glaube ich nicht verwunderlich, dass ich nur noch mit Ø 52 FPS rendere oder? (Mein PC ist nicht der beste, ein Laptop mit ner 8600M GT -> Minecraft läuft aber mit 60 FPS).

Dieser Beitrag wurde bereits 9 mal editiert, zuletzt von »Kippstrahl« (24.04.2011, 13:09)


15

24.04.2011, 12:16

du könntest eigentlich die flächen (ganz) unten weglassen, da diese nie betrachtet werden können ( außer durch cheating wo man aber trozdem gleich stirbt)

Zitat

Basically, there are only 10 types of people in the world. Those who know binary, and those who don't.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

16

24.04.2011, 13:11

Erstellst du deinen VertexBuffer auch im D3DPOOL_DEFAULT mit D3DUSAGE_WRITEONLY?
Du wirst wohl kaum jemals alle 134144 Vertices rendern müssen?

Abgesehen davon komm ich für einen Chunk aus 16x16x128 Würfeln auf maximal 2 * 16 * 16 + 4 * 16 * 128 = 8704 Außenflächen. Selbst wenn du das dann Brute Force als einfache unindizierte Dreiecksliste rendern willst (was du nicht solltest) brauchst du maximal 52224 Vertices. Wenn du indizierte Dreieckslisten verwendest (was du solltest) brauchst du sogar nur maximal (lässt sich wohl in den meisten Fällen noch weiter reduzieren) 34816 Vertices pro Chunk...

Edit: Ok ich hab nicht bedacht dass das Terrain ja ausgehöhlt werden kann. Aber selbst in diesem Fall sind niemals alle Würfelflächen Außenflächen. Wenn ich mich nicht täusche tritt die maximale Anzahl an Außenflächen auf wenn jeder zweite Voxel leer ist. Das entspricht maximal 8 * 8 * 64 * 6 = 24576 Flächen bzw. 98304 Vertices. Und dieser Fall wird praktisch nie eintreffen.

Ich würd mir evtl. überhaupt ein dynamisches System überlegen, also einen VertexBuffer anlegen der etwas mehr Platz bietet als notwendig. Wenn ein Chunk dann modifiziert wird und mehr oder signifikant weniger Platz braucht als momentan alloziert einfach einen neuen Buffer anlegen und fertig.

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »dot« (24.04.2011, 13:49)


Kippstrahl

Frischling

  • »Kippstrahl« ist der Autor dieses Themas

Beiträge: 18

Wohnort: Kiel

Beruf: 12.JG

  • Private Nachricht senden

17

24.04.2011, 19:59

Ja ich habe da was mit den Dimensionen verwechselt. Jedenfalls kann ich jetzt locker 16 Chunks mit voller FPS rendern und kriege alle Innenseiten "gecullt". Jetzt bin ich jedoch auf die Frage gestoßen, wie ich einzelne Seiten unterschiedlich texturieren kann. Mit VertexBuffern weiß ich nur, dass ich ab einem bestimmten Offset + Count rendere. Das würde jedoch bedeuten, dass ich wieder für jeden Würfel den Typ abfrage und somit wieder Face per Face rendere.

daG

Treue Seele

Beiträge: 130

Wohnort: Hamburg

  • Private Nachricht senden

18

24.04.2011, 20:07

Soweit ich weiß geht pro VBO nur eine Textur. Du müsstest daher eine Textur haben die alle möglichen Würfel-Texturen beinhaltet und dort mit TexCoords arbeiten. Die Koordinaten müsstest du ja nur am Anfang einmal berechnen und mit im VBO speichern.

Wenn du mehrere Texturen benutzen möchtest müsste es AFAIK über einen Shader gehen, aber Ahnung hab ich davon leider keine :)

Kippstrahl

Frischling

  • »Kippstrahl« ist der Autor dieses Themas

Beiträge: 18

Wohnort: Kiel

Beruf: 12.JG

  • Private Nachricht senden

19

24.04.2011, 20:51

Soweit ich weiß geht pro VBO nur eine Textur. Du müsstest daher eine Textur haben die alle möglichen Würfel-Texturen beinhaltet und dort mit TexCoords arbeiten. Die Koordinaten müsstest du ja nur am Anfang einmal berechnen und mit im VBO speichern.


Das ist eine gute Idee. So macht es Minecraft ja auch, fällt mir gerade auf.

dot

Supermoderator

Beiträge: 9 757

Wohnort: Graz

  • Private Nachricht senden

20

24.04.2011, 21:11

Soweit ich weiß geht pro VBO nur eine Textur. Du müsstest daher eine Textur haben die alle möglichen Würfel-Texturen beinhaltet und dort mit TexCoords arbeiten. Die Koordinaten müsstest du ja nur am Anfang einmal berechnen und mit im VBO speichern.

Exakt so macht man das normalerweise.

Werbeanzeige

Ähnliche Themen