2013-04-21 7 views
16

Ich stelle einen guten Ansatz vor, um so viele unzusammenhängende Geometrieteile mit einem einzigen Zeichenaufruf in OpenGL zu rendern, und die Wand, gegen die ich stehe, ist der beste Weg, wenn jedes Teil eine andere Übersetzung und vielleicht Rotation hat , da Sie nicht den Luxus haben, die Modellansichts-Uniform zwischen einzelnen Objekt-Draws zu aktualisieren. Ich habe ein paar andere Fragen hier und anderswo gelesen und es scheint, dass die Richtungen, in die die Leute zeigen, ziemlich unterschiedlich sind. Es wäre schön, die wichtigsten Methoden aufzulisten und zu versuchen, zu isolieren, was am häufigsten oder empfohlen ist. Hier sind die Ideen, die ich in Betracht gezogen habe:Was ist die beste Vorgehensweise für Batch-Zeichnungsobjekte mit unterschiedlichen Transformationen?

[edit: entfernt Erwähnung Instancing, da es nicht wirklich hier gilt]

  1. Erstellen von Matrixtransformationen im Shader. Hier würde ich einen Übersetzungsvektor oder vielleicht einen Drehwinkel oder eine Quaternion als Teil der Attribute senden. Der Vorteil ist, dass es plattformübergreifend einschließlich mobil funktioniert. Es scheint jedoch ein wenig verschwenderisch zu sein, die genau gleichen Transformationsdaten für jeden einzelnen Eckpunkt in einem Objekt als ein Attribut zu senden. Ohne Instanziierung müsste ich diese identischen Vektoren oder Skalare für ein einzelnes Objekt viele Male in einem VBO als Teil des Interleave-Arrays wiederholen, oder? Der andere Nachteil ist, dass ich mich auf den Shader verlassen muss, um die Mathematik zu machen; Ich weiß nicht, ob das weise ist oder nicht.

  2. Ähnlich wie bei 1), aber anstatt sich auf den Shader zu verlassen, um die Matrixberechnungen durchzuführen, mache ich stattdessen diese auf der Clientseite, sende aber immer noch die letzte Modellansichtsmatrix als 16 Floats in der VBO. Aber soweit ich das beurteilen kann, müsste ich diesen identischen Stream für jeden einzelnen Eckpunkt in der VBO wiederholen, oder? Scheint einfach verschwenderisch. Der Kompromiss mit 2) oben ist, dass ich mehr Daten in der VBO pro Vertex (16 Floats anstelle eines 3-Float-Vektors für die Übersetzung und vielleicht eine 4 Float-Quaternion) sende, aber dass der Shader weniger Arbeit verrichten muss.

  3. Überspringen Sie alle obigen Einschränkungen und kompromittieren Sie stattdessen mit einem separaten Zeichenaufruf für jedes Objekt. Dies wird typischerweise in den Büchern, die ich lese, "gelehrt", ohne Zweifel der Einfachheit halber.

Gibt es andere übliche Methoden als diese?

Als akademische Frage bin ich neugierig, ob alle oben genannten machbar und "akzeptabel" sind oder ob einer von ihnen eindeutig ein Gewinner über die anderen ist? Wenn ich ausschließlich Desktop-GL verwenden würde, ist das der primäre Weg, dies zu erreichen?

+3

Gute Frage, ich würde gerne eine Diskussion über die verschiedenen Vor- und Nachteile dieser verschiedenen Techniken sehen. –

+1

Dies ist viel zu hardware-spezifisch, um vernünftige oder genaue Empfehlungen für eine so große Vielfalt von Hardwareplattformen zu geben. Sogar eine Diskussion darüber, wann es angebracht ist, Instanziierung zu verwenden, ist zu hardware-spezifisch. Sie sprechen im Grunde von einem einmonatigen Profiling-Forschungsprojekt. –

+3

@NicolBolas Okay .... also lassen wir eine Diskussion über Instanziierung aus; Sagst du, dass eine Diskussion über die anderen Techniken keinen Sinn hat? Die Leute versuchen alles mit VBOs und Shadern, sicherlich gibt es einige allgemeine Ideen darüber, was zu beachten ist, oder Gründe, warum einige dieser Vorschläge überhaupt nicht gut sind, usw. – johnbakers

Antwort

11

Zwei Überlegungen:

Generell, wenn Sie mehrere Objekte haben, mit jedem Objekt unabhängigen Transformationen verwenden, verwenden Sie mehrere Zeichenaufrufe. Dafür gibt es . Die alte NVIDIA "Batch Batch Batch" -Präsentation zitiert zwischen 10.000 und 40.000 zeichnen Aufrufe pro Frame (in D3D. Mehr in GL) für eine 1-GHz-GPU. Heutzutage sieht man eher mehr als das. Also, wenn Sie mit Zehntausenden von einzelnen Objekten zu tun haben, alle von ihnen sind unterschiedlich (also keine Instanziierung), sind die Chancen gut, dass Sie werden gut.

Eine weitere Idee:

Nehmen Sie die Model-View-Matrix-Berechnungen aus dem Shader vollständig und gibt nur die Eckpunkte nach der Multiplikation.Dies ermöglicht einen einzelnen Zeichenaufruf für viele Objekte in verschiedenen Orientierungen und Übersetzungen. Die Kosten kommen nur bei allen CPU-Berechnungen an, aber ich nehme an, wenn dieser Engpass nicht so groß ist wie der Flaschenhals bei Mehrfachaufrufen, wäre es das wert.

(Entnommen aus here.)

5

Hier ist eine alternative Idee:

jeder Geben Sie ein Objekt-ID Vertex, die über ein Attribut in geben wird. Verwenden Sie dann diese ID im Vertex-Shader, um eine Suche in einer Textur durchzuführen, in der Sie Ihre Transformationsmatrizen speichern.

+0

Ah, Textur-Lookups. Sie wetten, ich mag es. Vielen Dank. – johnbakers

+0

Ich habe mit diesem Ansatz gespielt, es ist eine Art Sprites. Sie müssen natürlich jedes Mal die Textur drücken, aber es ist nur eine Handvoll, viel kleiner als die Ecken. In meinem vereinfachten Fall habe ich einfach vec4s in einer Zeile für xyz-Translation plus eine y-Rotation verwendet. Eine vollständige Matrix in der Textur wird möglicherweise nicht immer benötigt. –

Verwandte Themen