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

1

06.06.2009, 00:44

Geomipmapping (Cracks beseitigen)

Hi Spieleprogrammierer!

Ich arbeite schon etwas länger an einer Terrain Klasse, welche Geomipmaping unterstützt. Leider habe ich es immer weiter hinausgeschoben die Crackbeseitigung zu implementieren. Nun aber wo bereits sehr schöne Scenen in meinem Spiel zu sehen sind stören diese Cracks doch schon ein wenig und müssten dringend beseitigt werden. Wie es vom prinziep her funktioniert weiß ich, jedoch weiß ich nicht so wirklich wie ich das Implementieren soll. Bisher sieht das ganze bei mir so aus:

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
29
30
31
32
33
34
35
this->mIndexBuffer[0] = new IndexBuffer(this->mGraphicsDevice, sizeof(unsigned short), 32 * 32 * 6, SixteenBits);
    this->mIndexBuffer[1] = new IndexBuffer(this->mGraphicsDevice, sizeof(unsigned short), 16 * 16 * 6, SixteenBits);

    unsigned short* indices0;
    unsigned short* indices1;

    this->mIndexBuffer[0]->Lock(sizeof(unsigned short), 0, 32 * 32 * 6, (void**)&indices0);
    for(unsigned int x = 0; x < 32; ++x)
    {
        for(unsigned int y = 0; y < 32; ++y)
        {
            indices0[(x + y * 32) * 6 + 2] = (x    ) + (y    ) * 33;
            indices0[(x + y * 32) * 6 + 1] = (x + 1) + (y    ) * 33;
            indices0[(x + y * 32) * 6    ] = (x + 1) + (y + 1) * 33;
            indices0[(x + y * 32) * 6 + 3] = (x + 1) + (y + 1) * 33;
            indices0[(x + y * 32) * 6 + 4] = (x    ) + (y    ) * 33;
            indices0[(x + y * 32) * 6 + 5] = (x    ) + (y + 1) * 33;
        }
    }
    this->mIndexBuffer[0]->Unlock();

    this->mIndexBuffer[1]->Lock(sizeof(unsigned short), 0, 16 * 16 * 6, (void**)&indices1);
    for(unsigned int x = 0; x < 16; ++x)
    {
        for(unsigned int y = 0; y < 16; ++y)
        {
            indices1[(x + y * 16) * 6 + 2] = (x * 2    ) + (y * 2    ) * 33;
            indices1[(x + y * 16) * 6 + 1] = (x * 2 + 2) + (y * 2    ) * 33;
            indices1[(x + y * 16) * 6    ] = (x * 2 + 2) + (y * 2 + 2) * 33;
            indices1[(x + y * 16) * 6 + 3] = (x * 2 + 2) + (y * 2 + 2) * 33;
            indices1[(x + y * 16) * 6 + 4] = (x * 2    ) + (y * 2    ) * 33;
            indices1[(x + y * 16) * 6 + 5] = (x * 2    ) + (y * 2 + 2) * 33;
        }
    }
    this->mIndexBuffer[1]->Unlock();


Ich habe insgesammt 5 verschiedene LOD Stufen (hier nur 2 gezeigt)! Im rinziep setze ich bei den Indices je nach höhere Stufe immer größere abstä der zwischen den Indices, so das ein Quadrat nun 4 Quadrate abdeckt. Nun habe ich mir gedacht, das ich einfach am nochmals mehr IndexBuffer hinzufüge, und zwar 8 Stück dazu, bei denen an den Seiten des Patches die Vertices gleich mit den Vertices des Nachbarn liegen:


(Link)


Ich hoffe man kann erkennen was ich meine.

Nun Frage ich mich aber wie kann ich das einbauen? Wie denn die for Schleife dann bei mir aussehen müsste? Ich kann mir einfach nicht vorstellen wie das gehen soll?

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

2

06.06.2009, 08:59

Du brauchst innnerhalb der for Schleife einfach einen Haufen Ausnahmeregelungungen. So im Still von if(x == 31) { Hier drin müssen dann auch teilweise Indices übersprungen werden. }
Ist teilweise sehr sehr knifflig ich weiß.
Hab selber ein derartiges System mal gemacht, allerdings wollte ich mir Indexbuffer sparen und hab deswegen den äußeren Rand immer auf höchste Detailstufe gemacht - nicht sehr elegant, ging aber auf und war leichter zu implementieren, sowohl in der Generierung als auch in der Auswahl beim Rendern dann.

(Link)

3

21.06.2009, 18:41

So, dann muss ich wohl nochmal den alten Thread ausgraben :P

In der zwischenzeit habe ich mich ein wenig mit Indoor beschäftigt und bin damit soweit auch fertig, vorerst!

Jedoch bin ich in der zwsichenzeit auf ein Bildchen gestoßen, welches mich ein wenig nachdenken ließ.

http://www.gamasutra.com/features/20000228/figure_03.gif

Ich könnte mein Terrain immer so aufbauen, das es immer aus 3x3 Vertices besteht, die immer so wie im bild gezeigt aufgebaut sind. Beispielsweise bilden dann 8x8 von den Dingern die höchste detailstufe. Wenn dann ein übergang statt findet, kann ich sehr einfach aus 2 Vertices eines machen. Die undetaliertere Detailstufe besteht dann nur aus 4x4 dieser Dinger!

Bisher bin ich noch am überlegen welche vorteile diese dinger sonst noch bringen, und zum einen wähgre es der, das die indexbuffer für die verschieenen detail stufen nicht mehr so groß wären!

Nunja, ich wollte einfach mal fragen was ihr davon haltet?

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

4

21.06.2009, 19:39

Das ist eine ziemlich alte Methode um Terrain zu rendern. Sie hat durchaus viele Vorteile (lies einfach mal in dem Artikel nbischen dazu ;)). Der entscheidende Nachteil jedoch ist, dass es sehr schwer ist das Terrain ordentlich zu batchen: Man kriegt am Ende viel zu viele Drawcalls - und die sind ja bekanntlich schonmal grundsätzlich böööööööösseeeeee.

5

21.06.2009, 19:48

Nein, so meine ich das nicht :)

Die vertex und Indexbuffer sind immernoch genauso groß wie vorher, nur die anordnung der vertices ist nun ein wenig anders, so wird es dann einfacher die cracks zu beseitigen. Wie gesagt, ist nicht einer davon gleich 1 patch, sondern 8x8 von denen zusammen bilden ein Patch. Also muss ich um 64 von diesen dingern zu zeichnen lediglich einmal DrawIndexedPrimitive() aufrufen.

EDIT:

Habe mir mal den Artikel dazu durchgelesen und eigentlich hast du recht, man hat mehr drawcalls als beim geomipmapping, sofern das Terrain klein ist. Jedoch wenn das Terrain Größer wird, und man schon so 5km weit schauen kann, sind es gleich viele wenn nicht soger noch weniger draw calls!

Ich werde das ganze mal umsetzen und mit meinem alten Geomipmapping Algo vergleichen, bin mal gespannt was schneller ist. Aber habe das mal so Grob im Kopf ausgerechnet und um so größer das terrain ist, hat es im vergleich zu Geomipmapping immer weniger Drawcalls, da ein Patch nicht mehr eine Feste Größe hat, sondern bis ins unendlich wachseln kann.

Werbeanzeige