Uniforms
Während Vertex-Attribute für jeden Vertex unterschiedliche Werte liefern, verwenden wir Uniforms für Daten, die während eines Draw-Calls für alle verarbeiteten Vertices beziehungsweise Fragmente gleich bleiben.
Typische Beispiele sind die Richtung einer Lichtquelle, die Farbe eines Materials oder Einstellungen für die Beleuchtungsberechnung.
Uniforms in WGSL deklarieren
Abschnitt betitelt „Uniforms in WGSL deklarieren“In unserem Phong-Beispiel haben wir bereits Uniforms verwendet. Die benötigten Werte fassen wir in einer Struktur zusammen:
struct Uniforms { color: vec4f, lightDirection: vec4f, viewDirection: vec4f, ambientFactor: f32, diffuseStrength: f32, shininess: f32,};Anschließend deklarieren wir eine Variable, über die der Shader auf diese Daten zugreifen kann:
@group(0) @binding(0)var<uniform> uniforms: Uniforms;Dabei haben die einzelnen Bestandteile folgende Bedeutung:
var<uniform>legt fest, dass die Variable Daten aus dem Uniform-Adressraum enthält.@group(0)bezeichnet die Bind-Gruppe, über die die Daten bereitgestellt werden.@binding(0)bezeichnet den Eintrag innerhalb dieser Bind-Gruppe.uniforms: Uniformsgibt der Variablen ihren Namen und legt ihren Datentyp fest.
Die Werte stammen aus einem Uniform-Buffer, den wir wie gewohnt in JavaScript erstellen und über eine Bind-Gruppe bereitstellen.
Uniforms im Shader verwenden
Abschnitt betitelt „Uniforms im Shader verwenden“Auf die einzelnen Werte greifen wir über den Variablennamen und das entsprechende Feld der Struktur zu:
let lightDir = normalize(uniforms.lightDirection.xyz);let materialColor = uniforms.color.rgb;let ambient = uniforms.ambientFactor;So können wir dieselben Licht- und Materialeigenschaften bei der Verarbeitung vieler Vertices oder Fragmente verwenden.
Uniforms sind im Shader schreibgeschützt. Wir können ihre Werte lesen, aber nicht innerhalb einer Shader-Funktion verändern.
In JavaScript können wir dagegen den Inhalt des Uniform-Buffers zwischen Draw-Calls aktualisieren. So lassen sich beispielsweise die Lichtrichtung oder die Materialfarbe verändern, ohne den Shader-Code anzupassen.
Uniforms im Vertex- und Fragment-Shader
Abschnitt betitelt „Uniforms im Vertex- und Fragment-Shader“Uniforms können sowohl im Vertex-Shader als auch im Fragment-Shader verwendet werden.
Beide Shader-Stufen können auf dieselbe Uniform-Variable zugreifen, sofern die entsprechende Bindung für sie verfügbar ist.
Der Unterschied zu Vertex-Attributen ist dabei entscheidend: Vertex-Attribute liefern individuelle Daten für jeden Vertex. Uniforms stellen gemeinsame Werte bereit, die sich nicht von Vertex zu Vertex oder Fragment zu Fragment ändern.
Zusammenfassung
Abschnitt betitelt „Zusammenfassung“Uniforms verwenden wir für gemeinsame Shader-Daten wie Licht-, Material- oder Kameraeigenschaften.
In WGSL deklarieren wir sie mit var<uniform> und ordnen sie über @group und @binding einem Uniform-Buffer zu. Der Shader kann diese Werte lesen, während JavaScript den Buffer für spätere Draw-Calls aktualisieren kann.