Zum Inhalt springen

Interstage-Variablen

In unserem Phong-Beispiel haben wir die Normalen vom Vertex-Shader an den Fragment-Shader weitergegeben. Solche Werte bezeichnen wir in WGSL als Interstage-Variablen (inter-stage variables).

Sie ermöglichen es, Daten zwischen Shader-Stufen zu übertragen. Dabei können die Werte auf dem Weg vom Vertex-Shader zum Fragment-Shader interpoliert werden.

Schauen wir uns noch einmal die Ausgabestruktur unseres Vertex-Shaders an:

WGSL
struct VertexOutput {
@builtin(position) position: vec4f,
@location(0) normals: vec3f,
};

Die Position wird über @builtin(position) ausgegeben. Unsere Normale kennzeichnen wir dagegen mit @location(0).

Im Fragment-Shader empfangen wir diesen Wert über dieselbe Location:

WGSL
@fragment
fn fragmentMain(@location(0) normals: vec3f) -> @location(0) vec4f {
let normal = normalize(normals);
return vec4f(normal * 0.5 + vec3f(0.5), 1.0);
}

Die beiden @location(0)-Angaben verbinden die Ausgabe des Vertex-Shaders mit der Eingabe des Fragment-Shaders. Auch die Datentypen müssen übereinstimmen.

Der Fragment-Shader verwendet hier die empfangene Normale, um eine Farbe zu berechnen. Dadurch lässt sich die Ausrichtung der Oberfläche als Farbverlauf darstellen.

Der Vertex-Shader liefert für jeden Vertex eine Normale. Ein Dreieck besteht jedoch nicht nur aus seinen drei Eckpunkten, sondern bedeckt auch die Fläche dazwischen.

Damit der Fragment-Shader für die gesamte Dreiecksfläche eine Normale erhält, interpoliert WebGPU die ausgegebenen Werte zwischen den Vertices.

Standardmäßig erfolgt diese Interpolation perspektivisch korrekt. Im Fragment-Shader können wir die interpolierte Normale anschließend mit normalize() wieder auf die Länge 1 bringen, wie wir es bereits bei unserer Phong-Beleuchtung gemacht haben.

In GLSL, der Shading-Sprache von WebGL, werden solche zwischen den Shader-Stufen übertragenen Werte häufig als Varyings bezeichnet.

WGSL verwendet dafür kein eigenes Schlüsselwort varying. Stattdessen deklarieren wir die entsprechenden Ein- und Ausgaben mit @location.

Das Prinzip ist jedoch dasselbe: Der Vertex-Shader gibt Werte aus, die der Fragment-Shader für seine Berechnungen benötigt.

Interstage-Variablen übertragen Werte zwischen Vertex-Shader und Fragment-Shader. Die Zuordnung erfolgt in WGSL über passende @location-Angaben.

Bei der Rasterisierung werden diese Werte standardmäßig interpoliert. So erhält der Fragment-Shader beispielsweise die Normalen, die wir für unsere Phong-Beleuchtung benötigen.