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

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

11

18.08.2012, 13:26

Bitte ...
Aber das ist nicht meine Master-Arbeit, sondern "nur" ein Projekt.
Das hat normalerweise etwas weniger Umfang als eine Bachelor-Arbeit.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

12

18.08.2012, 16:31

Noch mal ne Frage zu ViewFrustum Culling: Wenn ihr eure Objekte in einer Szene in eine Baumstruktur unterteilt, um nicht mit jedem Objekt ViewFrustum-Culling Tests durchführen zu müssen, sondern eben mit größeren AABB oder OBB Clustern,
kann es aber auch passieren, dass ein paar Objekte in zwei dieser Tree-Leafs enthalten sind.
Die sollen aber nicht mehrfach gerendert werden. Wie löst ihr dieses Problem?
Eine Idee wäre z.B. in einer Hash-Map (std::map) zu speichern, ob ein Objekt schon mal gerendert wurde. Kann mir aber vorstellen, dass es relativ aufwändig ist, wenn diese Hash-Map in jedem Frame wieder gelöscht wird.
Hier mal ein Beispiel wie ich das meine:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void renderScene() {
    
    std::map<Model*, true> hashMap;
    
    treeLeafList = searchAllTreeLeafs(cameraViewFrustum);
    
    foreach (Leaf* leaf, treeLeafList) {
        foreach (Model* model, Leaf.modelList) {
            
            // Check if model has already been rendered
            if (hashMap.find(model) != hashMap.end())
                continue;
            
            hashMap[model] = true;
            
            model->render();
            
        }
    }
    
}

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

13

19.08.2012, 01:33

Da empfehle ich eine uralte Technik des "Moving Flags".

Ausgangspunkt: bool schonGezeichnetInDiesemPass;

Nachteil: muss man für alle Objekte zurücksetzen nach dem Pass. Stattdessen könnte man auch folgendes machen:

Quellcode

1
2
3
4
5
6
7
8
size_t mLetzterPassIndexGezeichnet;
void MalMich( size_t passIndex )
{
  if( passIndex == mLetzterPassIndexGezeichnet )
    return;

  mLetzterPassIndexGezeichnet = passIndex;
}


Ab jetzt musst Du nur noch den passIndex um eins erhöhen und kannst Du ersparen, alle bools zurückzusetzen.

bye, Thomas
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

14

19.08.2012, 07:47

Genau, das war auch mein Ansatz.
Frame-Nummer speichern, in der das Objekt zuletzt gerendert wurde.
Ich wusste nur nicht, dass das "Moving Flag" heißt.
Ein Wiki-Eintrag dazu wäre praktisch :)

15

19.08.2012, 09:51

kann es aber auch passieren, dass ein paar Objekte in zwei dieser Tree-Leafs enthalten sind.

Ich habe das bei mir so gelöst, dass Objekte, die am Rand von Knoten liegen, einfach so lange nach oben geschoben werden, bis sie nicht mehr auf einer Kante liegen.Der Nachteil ist natürlich, dass man für jeden Knoten dann auch alle Knoten berücksichtigen muss, die in höheren Ebenen liegen. Der Vorteil ist, man hat einen eindeutigen Knoten, zu dem das Objekt gehört, und kann beispielsweise beim verschieben oder für Kollisionstest direkt bei diesem Knoten anfangen.
Lieber dumm fragen, als dumm bleiben!

16

19.08.2012, 11:13

Zitat

Ich habe das bei mir so gelöst, dass Objekte, die am Rand von Knoten liegen, einfach so lange nach oben geschoben werden, bis sie nicht mehr auf einer Kante liegen.

So ähnlich habe ich es bei einem meiner Ansätze auch gelöst, jedoch nur geringfügig anders; ist eindeutig einfacher und schneller als die Methode Objekte mehreren Nodes zuzuweisen mit einem 'Schon-gezeichnet?-Flag'
Bei meiner Methode überprüfe ich im root-Node (das als Ausnahmeregel zählt da Objekte die zB auf dem Kreuzpunkt oder eindeutig zu gross sind) jedes Objekt auf Sichtbarkeit, bei teilweise im Frustum sichtbaren Nodes mache ich das selbe, alle anderen (Child) Nodes werden ohne weitere überprüfung gezeichnet.

Eine Anderer Ansatz könnte sein (Hab ihn selbst noch nicht getestet, war aber eine überlegung von mir)
Objekte werden auf ihre Faces reduziert (Dreiecke) und ins Octree geschrieben, im Octree werden diese noch in einer Liste Sortiert, nach Textur,Material,Shader ect... nachdem alle im Octree geschrieben sind kann man unabhängig vom Object die dreiecke nach sichtbaren Node rendern und da sortiert nach Material ect. spart man eine Menge calls, bzgl textur wechsel, shader calls ect...

Wie gesagt, keine ahnung ob das eine gute Lösung ist da selbst noch nicht endgültig getestet, meine aber das diese Methode recht gute Performance liefern dürfte...

Schrompf

Alter Hase

Beiträge: 1 470

Wohnort: Dresden

Beruf: Softwareentwickler

  • Private Nachricht senden

17

19.08.2012, 12:56

Die Aufteilung pro Dreieck geht nur für komplett statische Sachen. Kann man ansonsten aber auch machen. Und es bietet auch die Möglichkeit, die detailreduzierten Versionen der Meshes einen Knoten höher einzusortieren. Damit kannst Du bei hoher Entfernung einfach den großen Knoten rendern und hast einen großen Bereich der Szene mit einem Mal abgedeckt. Mache ich bei den Splitterwelten mit dem Terrain so. Alles andere wird nach Mittelpunkt einsortiert, so dass es immer nur in genau einem Knoten auftaucht, aber die AABB des Knotens wird entsprechend erweitert, so dass die Frustum-Tests den Knoten korrekt erfassen.

[edit] Der "Moving Flag" war eine Wortschöpfung von mir vor Ewigkeiten... ich bin recht sicher, dass irgendwer das schon vor mir erfunden hat und es demzufolge einen "richtigen" Namen dafür gibt.
Häuptling von Dreamworlds. Baut aktuell an nichts konkretem, weil das Vollzeitangestelltenverhältnis ihn fest im Griff hat. Baut daneben nur noch sehr selten an der Open Asset Import Library mit.

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

18

19.08.2012, 13:36

Ok ich fasse noch mal die Ideen zusammen:
1.) Objekte die in meheren Baum-Knoten sind soweit höher einsortieren bis dies nicht mehr der Fall ist
2.) Moving-Flag für jedes Objekt speichern (diese Idee hatte ich auch schon mal, war aber nicht sicher, ob das wirklich Sinnvoll ist bzw. ob das auch in projessionellen Game-Engine so gemacht wird)
3.) Objekte per Mittelpunkt in Baum-Knoten einsortieren und View-Frustum erweitern bzw. etwas groß-zügiger beim Culling-Test sein.

Ich denke die erste Variante gefällt mir am besten. Momentan sucht meine Tree-Search Implementierung nur nach den Blatt-Knoten aber das sollte sich ja leicht erweitern lassen.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

19

19.08.2012, 16:18

Entschuldige die späte Antwort gerade viel zu tun...
@TrommlBomml: Warum hältst du "Instancing" für eher exotisch? Ist das nicht sogar eher eine recht neue Technik?! (zumindest Hardware Instancing)
Exotisch im Sinne von der Menge an typischen Anwendungsfällen. Das erste was ich machen würde, ist meiner Meinung nach garantiert nicht Instancing. In der Regel hast du gar nicht soviel gleichartige Geometrie, dass sich das lohnt. Daher würde ich eher Schwerpunkt auf die anderen Dinge setzen: Culling, Batching und Texturatlanten.

Wenn ich an Torchlight denke, welches in Ogre mit einem spärlichen Instancing System ausgestattet war (jetzt wird gerade ein neues, wesentlich besseres implementiert), denke ich, dass es nicht DAS Kriterium für Performanceoptimierungen ist.

Soweit hab ich zumindest die Erfahrung gemacht! :)

LukasBanana

Alter Hase

  • »LukasBanana« ist der Autor dieses Themas

Beiträge: 1 097

Beruf: Shader Tools Programmer

  • Private Nachricht senden

20

19.08.2012, 17:09

Nun gut, aber gerade im Bezug auf Vegetation wie Gras, Bäume usw. ist Instancing wahrscheinlich gut umsetzbar und kann die Performance sicherlich steigern.

Werbeanzeige