Vektorkomponenten und Swizzling
Im vorherigen Kapitel haben wir gesehen, wie wir mit Vektoren mehrere Zahlen zu einem Wert zusammenfassen können. Ein vec3f enthält beispielsweise drei Komponenten, ein vec4f vier.
Häufig benötigen wir aber nicht den gesamten Vektor, sondern nur einzelne Komponenten. WGSL bietet dafür eine einfache Schreibweise mit dem Punktoperator.
Auf einzelne Komponenten zugreifen
Abschnitt betitelt „Auf einzelne Komponenten zugreifen“Betrachten wir einen Vektor mit vier Komponenten:
let position = vec4f(2.0, 4.0, 6.0, 1.0);Mit .x, .y, .z und .w können wir auf die einzelnen Werte zugreifen:
let x = position.x; // 2.0let y = position.y; // 4.0let z = position.z; // 6.0let w = position.w; // 1.0Die Bezeichnungen orientieren sich an den Koordinaten eines Vektors. Für Farben bietet WGSL zusätzlich die Namen .r, .g, .b und .a.
| Komponenten | Typische Verwendung |
|---|---|
x, y, z, w |
Positionen, Richtungen und Texturkoordinaten |
r, g, b, a |
Farben: Rot, Grün, Blau und Alpha |
Beide Schreibweisen greifen auf dieselben Komponenten zu. Der Unterschied liegt nur in ihrer Bedeutung für uns als Programmierer.
let color = vec4f(0.8, 0.4, 0.2, 1.0);
let red = color.r; // 0.8let alpha = color.a; // 1.0
let sameRed = color.x; // ebenfalls 0.8let sameAlpha = color.w; // ebenfalls 1.0Bei Farben sind rgba meist leichter zu verstehen, bei Positionen und Richtungen dagegen xyzw.
Welche Komponenten wir ansprechen können, hängt von der Größe des Vektors ab. Ein vec2f besitzt nur .x und .y beziehungsweise .r und .g. Der Zugriff auf .z wäre hier ungültig.
Mehrere Komponenten auswählen
Abschnitt betitelt „Mehrere Komponenten auswählen“Wir können auch mehrere Komponenten eines Vektors gleichzeitig auswählen. Diese Schreibweise heißt Swizzling.
let color = vec4f(0.8, 0.4, 0.2, 1.0);
let rgb = color.rgb;color.rgb wählt die ersten drei Komponenten aus. Das Ergebnis ist ein vec3f mit den Werten 0.8, 0.4 und 0.2.
Diese Schreibweise haben wir bereits in unserem Phong-Shader verwendet:
let color = uniforms.color.rgb;Unsere Uniform-Farbe ist ein vec4f. Für die Beleuchtungsberechnung benötigen wir jedoch nur die drei Farbkomponenten Rot, Grün und Blau. Mit .rgb erhalten wir sie direkt als vec3f.
Auch bei Positionen können wir mehrere Komponenten auswählen:
let position = vec3f(2.0, 4.0, 6.0);
let xy = position.xy; // vec2f(2.0, 4.0)let xz = position.xz; // vec2f(2.0, 6.0)Die Anzahl der ausgewählten Komponenten bestimmt den Typ des Ergebnisses:
| Ausdruck | Ergebnis | Typ |
|---|---|---|
position.x |
2.0 |
f32 |
position.xy |
(2.0, 4.0) |
vec2f |
position.xyz |
(2.0, 4.0, 6.0) |
vec3f |
Komponenten neu anordnen und wiederholen
Abschnitt betitelt „Komponenten neu anordnen und wiederholen“Beim Swizzling müssen wir die ursprüngliche Reihenfolge nicht beibehalten.
let color = vec4f(0.8, 0.4, 0.2, 1.0);
let reversed = color.bgr;reversed enthält vec3f(0.2, 0.4, 0.8). Die roten und blauen Farbkomponenten haben ihre Plätze getauscht.
Wir dürfen Komponenten auch mehrfach auswählen:
let repeated = color.rrr;Das Ergebnis ist vec3f(0.8, 0.8, 0.8).
Damit können wir beispielsweise aus einer einzelnen Farbkomponente einen Vektor mit drei gleichen Werten bilden.
Auch Kombinationen wie .xyx oder .wzyx sind möglich. Ein Swizzle darf eine bis vier Komponenten enthalten.
Regeln für Swizzling
Abschnitt betitelt „Regeln für Swizzling“Bei der Schreibweise müssen wir zwei Regeln beachten.
1. Die ausgewählten Komponenten müssen vorhanden sein.
Ein vec2f enthält nur zwei Komponenten. Deshalb ist .xy gültig, .xyz dagegen nicht.
let uv = vec2f(0.5, 0.25);
let swapped = uv.yx; // gültig// let invalid = uv.xyz; // ungültig2. Die Bezeichnungen dürfen innerhalb eines Swizzles nicht gemischt werden.
WGSL erlaubt die beiden Namensgruppen xyzw und rgba. Innerhalb eines Ausdrucks müssen wir aber bei einer Gruppe bleiben.
let color = vec4f(0.8, 0.4, 0.2, 1.0);
let a = color.xyz; // gültiglet b = color.rgb; // gültig
// let c = color.xgb; // ungültigDie Bezeichnungen s, t, p und q, die wir möglicherweise aus GLSL kennen, gehören nicht zu den WGSL-Komponentennamen.
Komponenten verändern
Abschnitt betitelt „Komponenten verändern“Bisher haben wir Komponenten nur gelesen. Bei einer veränderbaren Variablen können wir ihnen auch neue Werte zuweisen.
var color = vec4f(0.8, 0.4, 0.2, 1.0);
color.r = 1.0;color.g = 0.5;Danach enthält color die Werte vec4f(1.0, 0.5, 0.2, 1.0).
Auch mehrere Komponenten können wir gleichzeitig verändern:
var position = vec3f(1.0, 2.0, 3.0);
position.xy = vec2f(5.0, 6.0);Anschließend enthält position den Wert vec3f(5.0, 6.0, 3.0).
Bei einer Zuweisung dürfen die ausgewählten Komponenten nicht mehrfach vorkommen. Ein Ausdruck wie position.xx = vec2f(5.0, 6.0) wäre ungültig, weil wir dieselbe Komponente zweimal beschreiben würden.
Bei einer mit let deklarierten Variablen sind solche Änderungen ebenfalls nicht erlaubt, da ihr Wert nicht neu zugewiesen werden kann.
Zusammenfassung
Abschnitt betitelt „Zusammenfassung“Mit dem Punktoperator können wir auf die Komponenten eines Vektors zugreifen:
.x,.y,.z,.wverwenden wir vor allem für Koordinaten und Richtungen..r,.g,.b,.aeignen sich für Farben.- Mit Swizzling wie
.xy,.rgboder.bgrwählen wir mehrere Komponenten aus und können sie neu anordnen. - Komponenten dürfen beim Lesen mehrfach vorkommen, bei einer Zuweisung jedoch nicht.
Swizzling macht WGSL-Code kompakter und lesbarer. Statt einen neuen Vektor aus einzelnen Komponenten zusammenzusetzen, können wir häufig direkt die benötigten Werte auswählen.