Wie funktioniert dies in DirectX 11, dem Batching von Grundelementen für die Leistung, tatsächlich?

7

Ich scheine das nicht verstehen zu können. Microsoft sagt, dass eine der möglichen Optimierungen für eine Direct3D 11, wenn Grundelemente stapelweise aufgerufen werden sollen. Um beispielsweise 300 Dreiecke zu zeichnen, die jedes Mal die Draw-Methode aufrufen, müssen Sie stattdessen alle gleichzeitig packen und zeichnen.

Was ich nicht verstehe, ist, wie Sie sie tatsächlich an verschiedenen Orten und in allem zeichnen würden, weil ich zum Beispiel für jede eine andere Welttransformationsmatrix benötige. Das einzige, was mir in den Sinn kommt, ist, alles auf der CPU zu berechnen und die Werte für jeden Scheitelpunkt manuell festzulegen. Dieser Ansatz scheint mir jedoch keine sehr gute Codeoptimierung zu sein.

Ich habe das Gefühl, dass mir etwas fehlt, aber ich kann die Antwort nirgendwo finden. Die Frage ist: Wie können Sie Dinge in einen Draw-Aufruf packen, ohne dass sich der Renderstatus ändern muss, und trotzdem Objekte an verschiedenen Orten abrufen?

Beachten Sie, dass ich hier nicht nach Codeteilen frage, sondern hauptsächlich nach einer theoretischen Antwort darauf suche.

Kaboose
quelle

Antworten:

5

Es gibt viele Möglichkeiten, Batching durchzuführen. Aber für DX11 ist Instancing die beste Wahl, und es ist wirklich effizient und einfach zu bedienen!

Es gibt viele Ressourcen zur DX11-Instanzierung:

Rastertek-Instanzierung
MSDN-Instanzierungsreferenz

So funktioniert es: Sie erstellen einen zusätzlichen Puffer, der alle Worldtransform-Matrizen enthält. dass Sie an den Shader übergeben.

Von dort erhalten Sie eine "Perlayout" -Matrix, die jeder Instanz entspricht.

Die alte Methode besteht darin, die Weltposition für alle Dreiecke vor dem Zeichnen zu berechnen und dann die Matrix view_projection zu verwenden.

Tordin
quelle
Ich habe schon früher über Instanzen gelesen, war mir aber nicht sicher, worum es ging. Vielen Dank! Ich werde jetzt mehr darüber lesen.
Kaboose
4

Das einzige, was mir in den Sinn kommt, ist, alles auf der CPU zu berechnen und die Werte für jeden Scheitelpunkt manuell festzulegen. Dieser Ansatz scheint mir jedoch keine sehr gute Codeoptimierung zu sein.

Sie könnten dann überrascht sein.

Dies hängt natürlich von der Komplexität der Geometrie ab, die Sie zeichnen, und von den Transformationen, die Sie darauf anwenden. Sie müssen jedoch berücksichtigen, dass die durch DrawAufrufe verbrauchte CPU-Zeit nicht unerheblich ist. Es summiert sich sehr schnell, wenn Sie viele kleine Chargen haben. Wenn also die Geometrie und die Transformationen einfach sind, kann es sehr oft sehr sinnvoll sein, die (relativ teuren) DrawAnforderungen gegen (relativ billige) CPU-basierte Transformationen auszutauschen.

So funktioniert XNA SpriteBatch- es sammelt potenziell Tausende von Sprites in einem CPU-basierten Puffer, indem es Scheitelpunkte manuell transformiert, und sendet sie dann alle gleichzeitig an die GPU. Wenn Sie DrawHunderte oder Tausende von Sprites separat aufrufen, wird Ihre Framerate in die Knie gezwungen. Die Berechnung der Positionen ihrer Scheitelpunkte ist jedoch einfach und schnell. Es ist ein großer Gewinn.

Wie Tordin in seiner Antwort erklärt, können Sie mit Hardware-Instanzen Ihren Kuchen auch essen, was oft eine gute Idee ist. Die Idee, Grundelemente manuell zu stapeln, ist jedoch ein allgemeines Prinzip, das auch dann gilt, wenn keine Hardware-Instanzierung verfügbar ist.

Cole Campbell
quelle
Oh, dann ... wären Sie nicht besser dran, wenn Sie nur Software-Rendering verwenden würden? Wie GDI + oder so? Zum Beispiel für ein 2D-Sprite-basiertes Spiel.
Kaboose
1
Was lässt Sie denken, dass die Hardware-Transformation der einzige Vorteil des Renderns auf der GPU ist? Die GPU wird immer noch schneller beim Zeichnen der Sprites sein und über mehr Funktionen verfügen. Was lässt Sie denken, dass Sie in einem Sprite-basierten Spiel nur Sprites rendern müssen? Auch ein 3D-Spiel benötigt eine 2D-Oberfläche.
Cole Campbell
Lektion zu lernen: Wenn Leute zitieren "vorzeitige Optimierung ist die Wurzel allen Übels", ist es genau das, worüber sie sprechen. Sie haben die "beste" Option, die Microsoft anbietet, kurzerhand abgelehnt, weil Sie dachten, sie wäre nicht sehr schnell.
Patrick Hughes
Ich bin mir nicht sicher, wie das, was ich geschrieben habe, so ausgelegt werden könnte. Ich habe den Vorteil der manuellen Transformation von Batch-Primitiven erklärt, da dieses Konzept für Spieleentwickler wichtig ist. Ich habe absolut nichts "entlassen"; Hardware-Instanzen sind sehr wahrscheinlich die richtige Lösung für dieses Problem. Es ist jedoch für niemanden hilfreich, jemanden auf eine Lösung hinzuweisen, ohne die Kernprobleme zu erläutern, oder in diesem Fall, warum in der Microsoft-Dokumentation angegeben wurde, was er getan hat.
Cole Campbell
Das ist das Kaboose-Zitat "scheint keine sehr gute Codeoptimierung zu sein" und definitiv nicht Ihre Antwort, die ziemlich gut ist.
Patrick Hughes