Zum Inhalt springen

Vertex-Attribute

Vertex-Attribute liefern dem Vertex-Shader die Eigenschaften eines einzelnen Vertex, beispielsweise seine Position, Normale, Farbe oder Texturkoordinaten.

Wir haben solche Attribute bereits in unseren bisherigen Beispielen verwendet. Hier schauen wir uns genauer an, wie wir sie in WGSL deklarieren.

Aus unserem Phong-Beispiel kennen wir diese Schreibweise:

WGSL
@vertex
fn vertexMain(
@location(0) position: vec3f,
@location(1) normals: vec3f
) -> VertexOutput {
return VertexOutput(vec4f(position, 1.0), normals);
}

Der Vertex-Shader empfängt zwei Attribute: die Position und die Normale des jeweiligen Vertex.

Mit @location(0) und @location(1) legen wir fest, welcher Eingabe die jeweiligen Vertex-Daten zugeordnet werden. Die Verbindung zu den Vertex-Buffern wird wie gewohnt in JavaScript bei der Konfiguration der Render-Pipeline hergestellt.

Die Zahlen sind dabei frei wählbare Zuordnungen. Entscheidend ist, dass die Locations im Shader mit denen in der Pipeline-Konfiguration übereinstimmen.

Statt die Attribute einzeln als Funktionsparameter anzugeben, können wir sie auch in einer Struktur zusammenfassen:

WGSL
struct VertexInput {
@location(0) position: vec3f,
@location(1) normals: vec3f,
};
@vertex
fn vertexMain(input: VertexInput) -> VertexOutput {
return VertexOutput(vec4f(input.position, 1.0), input.normals);
}

Die Attribute sind dieselben. Lediglich ihre Deklaration ist anders organisiert.

Bei unserer bisherigen Schreibweise greifen wir direkt über position und normals auf die Werte zu. Mit einer Eingabestruktur verwenden wir dagegen input.position und input.normals.

Beide Varianten sind gleichwertig. Bei wenigen Attributen sind einzelne Funktionsparameter übersichtlich. Bei vielen Attributen kann eine Struktur den Code besser organisieren.

Auch in unserer VertexOutput-Struktur verwenden wir @location:

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

Hier bezeichnet @location(0) allerdings kein Vertex-Attribut aus einem Buffer, sondern einen Ausgabewert, den wir an den Fragment-Shader weitergeben.

Die Locations für Vertex-Eingaben und für die Übergabe an den Fragment-Shader gehören zu unterschiedlichen Schnittstellen. Deshalb dürfen beide unabhängig voneinander bei 0 beginnen.

Die ausgegebenen Normalen werden auf dem Weg zum Fragment-Shader interpoliert, wie wir es bereits von unserem Phong-Shading kennen.

Vertex-Attribute kennzeichnen wir in WGSL mit @location. Wir können sie entweder direkt als Parameter des Vertex-Shaders angeben oder in einer VertexInput-Struktur zusammenfassen.

Dabei unterscheiden wir zwischen den Locations für Vertex-Eingaben und den Locations für die Weitergabe von Werten an den Fragment-Shader.