2016-06-18 16 views
1

Ich schicke ein Dreieck in die Pipeline und möchte es in eine Sierpinski-Dichtung tessellieren. Es fühlt sich so an, als ob das mit der Instanziierung des Geometrie-Shaders so viel einfacher wäre, also sag mir bitte, ob die Idee, es mit Tessellations-Shadern zu machen, einfach falsch ist.Wie kann die ID des aktuellen Eckpunkts während der TES-Phase identifiziert werden?

Während der Tessellationskontrolle überprüfe ich die ID gegen 0-11 und speichere die Eckpunktposition und Farbe an der Position der aktuellen ID.

Ich definiere glPatchParameteri(GL_PATCH_VERTICES, 3); und layout(vertices = 12) out; für meine Tesselation Control Shader, wie ich jedes Dreieck in 4 Dreiecke tesselated wollen.

Es sieht aus wie während meines Tessellation Evaluation Shader die in vec3 tcPosition[]; und in vec3 tcColor[]; Arrays die richtigen 12 Werte in der richtigen Reihenfolge enthalten. Allerdings: Wie ordne ich sie bei der Auswertung richtig zu? Gibt es so etwas wie gl_primitiveID während der Tessellation-Auswertung? Ich würde einen Ersatz für gl_primitiveID benötigen, der 0 für alle generierten Scheitelpunkte ist, da sie aus dem gleichen Patch hervorgebracht werden. Zur Zeit verwende ich nur die Information der ersten drei Eckpunkte (0, 1, 2), aber ich müsste diese Indizes nach jedem generierten Dreieck um 3 verschieben.

void main(){ 
    vec3 p0 = gl_TessCoord.x * tcPosition[0]; 
    vec3 p1 = gl_TessCoord.y * tcPosition[1]; 
    vec3 p2 = gl_TessCoord.z * tcPosition[2]; 
    tePosition = p0 + p1 + p2; 
    teColor = gl_TessCoord.x * tcColor[0] + gl_TessCoord.y * tcColor[1] + gl_TessCoord.z * tcColor[2]; 
    gl_Position = mvp * vec4(tePosition, 1); 
} 

Keine Erkenntnisse oder Ideen, wie tessellate das Dreieck geschickt, so dass ich später in der Lage bin Feedback für Ping-Pong-Rendering verwendet verwandeln werden sehr geschätzt.

Antwort

1

Ich schicke ein Dreieck in die Pipeline und möchte es in eine Sierpinski-Dichtung tessellieren.

Stop. Das kannst du nicht tun.

Die Dreiecks-Tessellation wird nicht so durchgeführt, dass Sie dies generieren können. Die particular tessellation algorithm required for tessellation wurde entwickelt, um die Verbindung von Kanten zu erleichtern. Es ist auch darauf ausgelegt, eine adaptive und glatte Tessellation zu ermöglichen.

Sierpinski triangles haben diese Eigenschaften nicht.

Wenn Sie solch eine strenge Kontrolle über die genauen Mittel der Tessellation benötigen, würde ich vorschlagen, die Tessellation auf der CPU zu tun. Ein GS wäre nicht in der Lage, ein Dreieck fein genug zu tessellieren; die meisten OpenGL-Implementierungen erlauben dem GS nicht, so viele Dreiecke auszugeben, sogar mit geometry shader instancing.

Was die Einzelheiten Ihrer Frage:

Ich definiere glPatchParameteri(GL_PATCH_VERTICES, 3); und Layout (Eckpunkte = 12) aus; für meinen Tesselation Control Shader, wie ich will, dass jedes Dreieck in 4 Dreiecke geplottet wird.

So funktioniert Tesselation nicht.

Jeder Patch, der den tessellation primitive generator (der Schritt nach dem TCS), egal wie viele Ecken hat, gilt als ein einzelne primitive wird tessellated erreicht. Ihr TCS gibt hier 12 Eckpunkte in einem Patch aus, aber der Patch selbst ist immer noch ein einzelnes Dreieck.

Wenn Sie die Anzahl der Vertices steuern können, können Sie definieren, was ein "Vertex" für Ihren Tessellationsalgorithmus bedeutet. Zum Beispiel hat eine Bezier-Oberfläche 16 Kontrollpunkte Vertices, aber es ist immer noch ein Quad. Dies ermöglicht einem Bezier-basierten TES, alle 16 Kontrollpunkte als Eingaben zu nehmen, wenn Eckpunkte erzeugt werden.

Auch Tessellation funktioniert nicht basierend auf der Frage, wie viele Dreiecke Sie bekommen. Es funktioniert, basierend auf wie viel Unterteilung Sie wollen. Das sind die äußeren und inneren Tessellationsebenen: die Anzahl der Segmente, in die die Kanten des Dreiecks tesselliert werden.

Allerdings: Wie ordne ich sie richtig während der Auswertung?

Die Eingänge des TES sind die gleichen Werte die TCS schrieb. In der gleichen Reihenfolge.

Die Art und Weise Tessellation funktioniert ist, dass was Tessellated ist nicht Ihre Vertices von der TCS geschrieben. Was tesselliert wird, ist ein abstract patch. Der Tessellation-Primitivgenerator erzeugt "Vertices" in Bezug auf das abstrakte Patch.

Die gl_TessCoord ist, was Sie erkennen können, wo eine bestimmte TES-Aufruf innerhalb der abstrakten Patch ist. Dann kombinieren Sie das mit den Ausgangsdaten des TCS (die Eingaben in das TES sind), um die für diese Koordinate benötigten Vertex-Werte zu erzeugen.

Ich müsste einen Ersatz für gl_primitiveID, die 0 für alle generierten Vertices ist, wie sie aus dem gleichen Patch erstellt werden.

Das tut es schon. gl_PrimitiveID ist für jeden TES-Aufruf in einem einzigen Patch identisch.

+0

Vielen Dank für das ausführliche Feedback. Dies hat mir geholfen, nicht zusätzliche Tage in den Versuch zu investieren, einen Weg zu finden, Arbeit zu machen, was nicht funktionieren kann. Ich werde mit der GS fortfahren, da ich weiß, wie viele Rekursionsebenen zusammen mit Ping-Pong-Rendering verwendet werden können (ein Durchgang gibt 12 Eckpunkte pro Dreieck aus und dann wird das Ergebnis mit Transformations-Feedback zurückgelesen und dann komplett gestartet neue Iteration). – NoxMortem

+1

@NoxMortem: "* Ein Durchlauf gibt 12 Scheitelpunkte pro Dreieck aus und dann wird das Ergebnis mit Transformationsrückmeldung zurückgelesen, dann wird eine komplett neue Iteration gestartet *" ... An diesem Punkt wäre es schneller, die CPU zu verwenden. Alles, was vor dem Start der nächsten Iteration anhält, ist langsamer als ein optimierter CPU-Algorithmus. Zumindest könnten Sie einen Compute Shader verwenden. –