2014-04-21 19 views
7

Da der Vertex-Shader einmal pro Vertex ausgeführt wird (dh im Dreieck dreimal), wie wird die variierende Variable für jedes Fragment berechnet, wenn es (wie im Beispiel) nur dreimal zugewiesen wird?Wie interpoliert OpenGL variierende Variablen auf dem Fragment-Shader, selbst wenn sie nur drei Mal auf dem Vertex-Shader gesetzt sind?

Fragment-Shader:

precision mediump float; 
varying vec4 v_Color; 

void main() { 
    gl_FragColor = v_Color; 
} 

Vertex-Shader:

attribute vec4 a_Position; 
attribute vec4 a_Color; 

varying vec4 v_Color; 

void main() { 
    v_Color = a_Color; 
    gl_Position = a_Position; 
} 

Also, die Frage ist, wie funktioniert das System hinter diesem Know, wie die Variable v_Color bei jedem Fragment zu berechnen, da diese Der Shader weist v_Color nur 3 Mal zu (in einem Dreieck).

+0

Es interpoliert den Wert zwischen den drei Ecken, was es bedeutet, eine variierende Variable zu sein. –

+0

Können Sie mir bitte sagen, wie gehen die inneren Prozesse? Wie misst es die Entfernung? (Sorry für meinen Mangel an Wissen, konnte aber nichts anderes im Internet finden.) – ViliX64

+1

Ich bin nicht so erfahren mit GLSL, ich hatte gehofft, dass jemand anderes die Frage beantworten würde. Aber im Grunde, wenn Ihre Scheitelpunkte zehn Pixel voneinander entfernt sind, wird jedes Pixel zwischen den Scheitelpunkten eine interpolierte Farbe erhalten, die 1/10 zu der anderen Farbe ist, dann 2/10, 3/10 usw. –

Antwort

4

Alle Ausgaben des Vertex-Shaders sind pro Vertex. Wenn Sie v_Color in dem Vertex-Shader festlegen, wird es auf dem aktuellen Scheitelpunkt festgelegt. Wenn der Fragment-Shader ausgeführt wird, liest er den v_Color-Wert für jeden Eckpunkt im Grundelement und interpoliert zwischen ihnen basierend auf der Position des Fragments.

3

Zunächst ist es ein Fehler anzunehmen, dass der Vertex-Shader einmal pro Vertex ausgeführt wird. Beim indizierten Rendern kann die primitive Assembly in der Regel auf den Post-Cache (Ergebnis früherer Vertex-Shader-Aufrufe) basierend auf dem Vertex-Index zugreifen, um die mehrmalige Auswertung eines Vertex zu eliminieren. Neue Dinge wie Geometrieshader können jedoch leicht zum Zusammenbruch führen.

Wie der Fragment-Shader seinen Wert erhält, wird normalerweise während der Rasterung gemacht. Diese Vertex-Attribute werden entlang der Oberfläche des Grundelements (Dreieck in diesem Fall) basierend auf dem Abstand des Fragments relativ zu den Vertices interpoliert, die zum Erstellen des Grundelements verwendet wurden. In DX11 kann die Interpolation so lange verschoben werden, bis der Fragment-Shader selbst läuft ("Pull-Model" -Interpolation genannt), aber das ist normalerweise etwas, das während der Rasterung passiert.

+0

Wenn die Implementierung die Ausgaben des Vertex-Shaders zwischenspeichert, dann wird afaik festgestellt, dass ein zweiter Aufruf des Vertex-Shaders für diesen Vertex zu keinem anderen Ergebnis führen kann Werte, so ist der Punkt strittig. –

+0

@ColonThirtyTwo: Es gibt tatsächlich begrenzte Kapazität für den Post-T & L-Cache und es ist traditionell FIFO, aus diesem Grund kann die Bereitstellung von Vertices in Lokalität optimierte Reihenfolge wie * strip-order * die Leistung verbessern, auch wenn Sie nicht tatsächlich die Vertices als verwenden strip (was meistens die Anzahl der Indizes speichert, die Sie speichern müssen). Geometrie-Shader verschlimmern die Situation durch die Einführung einer zweiten Schicht von Daten, die zwischengespeichert werden müssen. Dies betrifft jedoch vor allem die maximale Anzahl gleichzeitiger Aufrufe eines GS und die Größe des Post-GS-Cache wurde bei der Tessellation weitgehend berücksichtigt. –

+0

Richtig, aber diese haben keinen Einfluss auf das fertige Bild. Für jemanden, der aussieht, als würde er gerade OpenGL lernen und sich keine Gedanken über Effizienz machen, scheint es eine technische Sache zu sein. –