2017-10-07 20 views
1

Ich habe einige grundlegende Metall-Rendering gelernt, und ich bin mit einigen grundlegenden Konzepte stecken:Wie oft wird der Vertex-Shader mit Metall bezeichnet?

Ich weiß, dass wir Vertex-Daten an einen Shader mit schicken:

renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0) 

Und dann können wir es abrufen im Shader mit:

vertex float4 basic_vertex(const device VertexIn* vertexIn [[ buffer(0) ]], unsigned int vid [[ vertex_id ]]) 

Wie ich es verstehe, wird die Vertex-Funktion für jeden Scheitelpunkt einmal aufgerufen werden, und vertex_id wird bei jedem Aufruf aktualisiert den Vertex-Index enthalten.

Die Frage ist, woher kommt die Vertex_ID?

renderEncoder.setVertexBuffer(vertexBuffer, offset: 0, index: 0) 
renderEncoder.setVertexBuffer(vertexBuffer2, offset: 0, index: 1) 

Wenn Vertex hat drei Elemente, und vertexBuffer2 hat 10 Elemente ... wie oft ist die Vertex-Funktion aufgerufen:

ich an die Shader mehr Daten mit unterschiedlichen Größen schicken könnte? 10?

Danke!

Antwort

3

Das wird durch den Zeichenaufruf bestimmt, den Sie auf dem Render-Befehlscodierer machen. Nehmen Sie die einfachste Zeichenmethode:

drawPrimitives(type:vertexStart:vertexCount:) 

Die vertexCount legt fest, wie oft Ihre Vertex-Funktion aufgerufen wird. Die Scheitelpunkt-IDs, die an die Scheitelpunktfunktion übergeben werden, sind solche im Bereich von vertexStart bis vertexStart + vertexCount - 1.

Wenn Sie eine andere Zeichenmethode betrachten:

drawPrimitives(type:vertexStart:vertexCount:instanceCount:) 

, dass die gleiche Palette von Vertex-IDs übergeht. Es ruft jedoch Ihre Scheitelpunktfunktion vertexCount * instanceCount mal auf. Es wird instanceCount Aufrufe mit der Scheitelpunkt-ID vertexStart sein. Die Instanz-ID reicht von 0 bis instanceCount - 1 für diese Anrufe. Ebenso gibt es instanceCount Aufrufe mit der Scheitelpunkt-ID vertexStart + 1 (unter der Annahme vertexCount >= 2), eine mit jeder Instanz ID in [0..instanceCount-1]. Usw.

Die anderen Zeichenmethoden haben verschiedene andere Optionen, aber sie beeinflussen meistens nicht, wie oft die Eckenfunktion aufgerufen wird. Beispielsweise verschiebt baseInstance den Bereich der Instanz-IDs, aber nicht seine Größe.

Die verschiedenen drawIndexedPrimitives()-Methoden rufen die spezifischen Vertex-IDs aus einem Puffer ab, anstatt alle Vertex-IDs in einem Bereich aufzulisten. Dieser Puffer kann eine gegebene Eckpunkt-ID an mehreren Orten enthalten. Für diesen Fall glaube ich nicht, dass definiert ist, ob die Scheitelpunktfunktion für dieselbe Scheitelpunkt-ID und Instanz-ID mehrfach aufgerufen werden kann. Metall wird vermutlich versuchen, Duplizierungsaufwand zu vermeiden, aber es könnte am Ende tatsächlich schneller sein, die Vertex-Funktion für jeden Index im Indexpuffer aufzurufen, selbst wenn mehrere solcher Indizes die gleiche Vertex-ID haben.

Die Beziehung zwischen Scheitelpunkten und Daten in Puffern, die Sie an die Vertex-Verarbeitungsstufe übergeben, liegt ganz bei Ihnen. Sie müssen überhaupt keine Puffer passieren. Zum Beispiel könnte eine Vertex-Funktion Vertex-Informationen vollständig rechnerisch nur aus der Vertex-ID und der Instanz-ID erzeugen.

Es ist natürlich ziemlich üblich, dass zumindest einige der Puffer Arrays von Daten pro Vertex enthalten, die zur Verwendung der Vertex-ID indiziert sind. Andere Puffer können einheitliche Daten sein, die für alle Scheitelpunkte gleich sind (dh Sie indexieren nicht mit der Scheitelpunkt-ID in diesen Puffer). Der Metal selbst weiß das aber nicht.

Verwandte Themen