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

01.02.2010, 15:02

Verständnisfrage culling & dann rendern

Hallo,

wie die Überschrift schon sagt habe ich ein Verständnisproblem damit, wie ich die Polygone render, nachdem ich sie auf Sichtbarkeit getestet habe.

Ich überprüfe als erstes ob das Poylgon (oder wird das nicht für jedes Polygon gemacht?) sichtbar ist und render es -> dann würde ich für jedes Polygon einen drawCall machen. Das kann also so nicht sehr Performant sein.

Oder merke ich mir die Indizes und fülle in jedem Frame den Indexbuffer neu?

Wie ist die "gängige" Vorgehensweise beim rendern?

Danke Ludwig

Tobiking

1x Rätselkönig

  • Private Nachricht senden

2

01.02.2010, 15:31

Einzelne Polygone werden gar nicht getestet, da die Grafikkarte diese schneller rendert als das man diese auf Sichtbarkeit prüfen kann. Es lohnt sich nur wenn man viele Polygone mit einer einfachen Berechnung ausschließen kann.

Eine Methode wäre z.B. sich zu einem Vertexbuffer zusätzlich eine Art Bounding Box zu speichern und diese auf Sichtbarkeit zu prüfen. Ist diese Box nicht sichtbar, dann braucht der ganze Buffer nicht gerendert werden. Sollte die Box doch zum Teil im Sichtfeld liegen wird dieser komplett gerendert. Das ganze kann man auch noch Baumartig machen wie z.B. beim Octree.

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

3

01.02.2010, 16:04

Folgende Vorgehensweise:

- Als erstes die Welt in Einzel-Objekte unterteilen.
- Von jedem Objekt musst du dessen Boundingbox kennen, sprich den jeweils niedrigsten und höchsten X,Y und Z-Wert
- Beim Zeichnen multiplizierst du die Eckpunkte dieser Boundingbox dann mit der Model-und Camera-Matrix, um die Positionen der Eckpunkte aus "deiner Sicht" zu erhalten
- Anschließend testest du ob sich diese Box in deinem Sichtkegel befindet, in Google zu finden unter "Frustum Culling"
- Wenn du es noch etwas optimieren willst unterteilst du deine Objekte noch in einzelne Unterobjekte und testest dann quasi hierarchisch nach unten.

Bei Dingen wie z. Bsp. einer Landschaft verfährst du ähnlich. Hier kannst du z. Bsp. erst für eine 128x128m große Fläche die Boundingbox ermitteln und dessen "Kinder" sind dann 64x64 große Flächen, dessen dann 16x16m große Flächen usw. usw., die du dann auch jeweils wieder gegen das Frustum testest.

Ab wie vielen Dreiecken man unterteilt ist extrem Grafikkarten abhängig. Vor 10 Jahren hat es noch gelohnt 200 Dreiecke nochmal zu unterteilen, heute wohl eher erst ab einigen Tausend, muss man einfach ausprobieren.

Wenn man dann noch mehr rauskitzeln will, kann man Techniken wie BSP-Trees, Portale oder Software-Occlusion-Culling angehen, aber Frustum-Culling ist eigentlich immer der erste Schritt, weils sehr simpel zu handhaben ist.

Bzgl. der Vorgehensweise beim Rendern:

Culling-Thread:
1. Ermitteln welche Objekte überhaupt zu sehen sein sollen und sich in Sichtweite befinden -> Liste A
2. Culling (Frustum Culling, BSP etc.) -> alle aus Liste A verbliebenen in Liste B
3. Liste sortieren (z. Bsp. nach Textur, Shader etc. pp)
4. Liste an Render Thread übergeben
5. Warten bis Render-Thread Liste "abgeholt hat" (sonst "schlafen")

Render Thread (Der in dem du Direct3D/OpenGL initialisierst, Texturen lädst et.c pp.):
1. Neue Liste abholen (sonst "schlafen")
2. Liste ausgeben

LG
Alyx

4

01.02.2010, 16:31

danke für die super Erklärungen, das hilft mir weiter! Nur tritt dann in meinem Kopf (technisch nicht medizinisch :D) das nächste Problem auf : Wenn ich eine Liste habe in der nach z.B. Texturen sortiert ist (alle Polygone die die gleiche Textur haben) habe und diese render müsste ich doch wieder für jedes Polygon einen renderCall machen oder den Indexbuffer neu füllen, da ich ja nicht sagen kann ob die Polygone mit den gleichen Texturen nebeneinander liegen.

Beiträge: 774

Beruf: Student

  • Private Nachricht senden

5

01.02.2010, 16:49

Wenn du deine Geometrie nach Texturen gebündelt bzw. sortiert hast, dann musst du doch nicht für jedes Polygon sondern für jedes dieser Objekte einen Rendercall durchführen ;)

In der Regel hat man eh Modelle mit kaum mehr als 3 Materialien (meistens eh nur eins) und somit Texturen. Somit kann man diese dadurch definierten Bündel recht leicht abarbeiten.

Alyx

Treue Seele

Beiträge: 236

Wohnort: Hannover

Beruf: Head Of Software Development

  • Private Nachricht senden

6

01.02.2010, 17:16

Zitat von »"Wümpftlbrümpftl"«

In der Regel hat man eh Modelle mit kaum mehr als 3 Materialien (meistens eh nur eins) und somit Texturen. Somit kann man diese dadurch definierten Bündel recht leicht abarbeiten.


Genau. Simples Beispiel: Du hast ein Haus mit einem Material für's Dach und einem Material für die Wände. Dann unterteilst du es bereits beim Konvertieren bzw. beim Laden so in Einzelobjekte, dass am Ende jedes Objekt genau ein Material hat. Im Fall des Hauses heißt das:
Du erstellst ein neues Objekt Haus, dass 2 Kinder hat, Dach und Wand.

Zur Laufzeit gibst du dann wie gehabt das Objekt Haus aus, dass dann seine 2 Kinder zur Ausgabe-Liste hinzufügt, bei der man sich nun darum keine Sorgen mehr bzgl. Material/Textur machen musst. Würdest du dann 20x sagen Draw(House) würde er beim Zeichnen dann erst die 20 Dächer und dann die 20 Wände malen. (oder genau anders herum ;-)

LG
Alyx

Werbeanzeige