Gibt es eine Möglichkeit, Grundelemente in einem Geometrieshader ohne Eingabegeometrie zu generieren?

17

Vor ein paar Jahren habe ich versucht, dieses GPU-Juwel in OpenGL zu implementieren , um mithilfe von Marching Cubes prozedurales 3D-Terrain zu generieren . Der Artikel schlägt vor, Marching Cubes in einem Geometrie-Shader mit maximaler Effizienz zu implementieren. Das bedeutet, dass ich den Shader einmal für jedes Voxel in der Domäne ausführen muss und die gesamte Geometrie in dieser Zelle generieren muss.

Ein Problem, über das ich gestolpert bin, war, wie man den Geometrie-Shader zum Laufen bringt, ohne tatsächlich etwas außerhalb dieses Shaders zu rendern. Meine Lösung (die ziemlich schwierig zu sein schien) bestand darin, einen Punkt in jeder Zelle zu rendern, ihn mit dem Geometrie-Shader zu verwerfen und stattdessen meine Dreiecke auszusenden. Ich habe nie eine richtige Lösung gefunden und diese Problemumgehung blieb im endgültigen Code erhalten.

Gibt es also eine Möglichkeit, OpenGL anzuweisen, einen Rendering-Durchlauf vom Geometrie-Shader ohne Eingabegeometrie zu starten? Oder muss ich immer ein paar Dummy-Punkte an die GPU senden, um die Dinge zum Laufen zu bringen.

Martin Ender
quelle

Antworten:

15

Nein, dazu gibt es eigentlich keinen Weg.

Ein Aufruf eines Geometrie-Shaders erfordert ein Eingabeprimitiv und generiert 0 oder mehr Ausgabeprimitive. Ohne ein Eingabeprimitiv gibt es keine Möglichkeit, den Geometrie-Shader tatsächlich aufzurufen . Natürlich können Sie die Grenzen der maximalen Anzahl von Ausgabeprimitiven des Geometrie-Shaders für jedes Eingabeprimitiv verlängern (kennen die praktischen Grenzen derzeit nicht, sollten in der Größenordnung von Tausenden liegen). So könnten Sie vielleicht 1024 Dreiecke für jeden Punkt erzeugen, aber Sie müssen immer einige Eingabeprimitive haben.

Was Sie jedoch nicht benötigen, ist ein tatsächlicher Begriff der Geometrie. Sie müssen 3D-Punkte nicht wirklich an einer vernünftigen Position rendern, sie können auch nur einige abstrakte Index- oder Texturkoordinaten oder was auch immer als Attribute haben und müssen nicht unbedingt eine aussagekräftige 3D-Position haben.Niemand bestimmt, welche Attribute Ihre Eckpunkte haben. Sie können auch Scheitelpunkte ohne Attribute rendern . Sie müssen jedoch einige Grundelemente rendern , um den Geometrie-Shader für sie aufzurufen, auch wenn diese Grundelemente keine tatsächlichen Attribute aufweisen (die Berechnung der Ausgabegeometrie im Geometrie-Shader ist jedoch eine andere Frage).

Aber was Sie tatsächlich getan haben, einen Punkt für jede Gitterzelle zu rendern und daraus die marschierenden Würfel-Dreiecke für diese Zelle zu generieren, ist genau der direkte Ansatz. Natürlich liegt es an Ihnen, welche Attribute diese Zelle enthält. Es kann sich um eine 3D-Position handeln, eine Textkoordinate in eine 3D-Textur, was auch immer, aber das sind die Rasterzellen, die Sie rendern. Rein semantisch gesprochen "verwirft" man diese Punkte nicht und "ersetzt" sie dann durch Dreiecke, sondern "konvertiert" jeden Punkt in eine Gruppe von Dreiecken. Genau dafür ist der Geometrie-Shader gedacht, und nichts ist "hacky" oder "unsachgemäß". Niemand sagt, dass der Geometrie-Shader den gleichen Ausgabe-Primitiv-Typ erzeugen muss, der eingegeben wurde, um "richtig" zu sein .


Was Sie tun können, um ein weitgehend eingabefreies Rendern Ihres Voxel-Gitters zu erreichen (und das könnte das sein, wonach Sie eigentlich gefragt haben), wäre, einfach eine Reihe von attributlosen Punkten zu zeichnen. Dies bedeutet, dass Sie überhaupt keine Attribut-Arrays benötigen und sie einfach alle deaktivieren und ein einfaches aufrufenglDrawArrays mit der Anzahl der Zellen , die Sie benötigen. Dann können Sie im Vertex-Shader oder im Geometrie-Shader den erforderlichen 3D-Gitterzellenindex mit ein wenig Indexmagie aus der eingegebenen Vertex-ID (dh gl_VertexIDder einzigen Information, die Sie haben) generieren und dann Ihre Marschwürfel-Geometrie aus einem Lookup in berechnen die 3D-Volumentextur (oder welche Datenstruktur auch immer).

Also, im Nachhinein sollte ich meine Aussage von Anfang an relativieren: Sie nicht Primitiven ohne Eingabe erzeugen können Primitive , aber man kann sich ohne Eingabe erzeugt Geometrie .

Chris sagt Reinstate Monica
quelle