WebGL - Shaders: Ein Anfängerleitfaden

Hallo, angehende Programmierer! Heute machen wir uns auf eine aufregende Reise in die Welt der WebGL Shaders. Machen Sie sich keine Sorgen, wenn Sie noch nie eine Zeile Code geschrieben haben – ich werde Ihr freundlicher Guide durch diese bunte Landschaft der Computergrafik sein.

WebGL - Shaders

Was sind Shaders?

Bevor wir eintauchen, lassen Sie uns verstehen, was Shaders sind. Stellen Sie sich vor, Sie malen ein Bild. Die Leinwand ist Ihr Bildschirm, und Shaders sind wie magische Pinsel, die dem Computer genau sagen, wie jeder Pixel koloriert werden soll. Cool, oder?

Datentypen

In der Shader-Welt haben wir einige besondere Datentypen, mit denen wir arbeiten können. Sehen wir uns diese an:

Datentyp Beschreibung Beispiel
float Eine Einzelfach Genauigkeit Fließkommazahl 3.14
vec2 Ein 2D-Vektor vec2(1.0, 2.0)
vec3 Ein 3D-Vektor vec3(1.0, 2.0, 3.0)
vec4 Ein 4D-Vektor vec4(1.0, 2.0, 3.0, 4.0)
mat2 Eine 2x2-Matrix mat2(1.0, 2.0, 3.0, 4.0)
mat3 Eine 3x3-Matrix mat3(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
mat4 Eine 4x4-Matrix mat4(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0)

Machen Sie sich keine Sorgen, wenn diese überwältigend erscheinen – wir werden sie Schritt für Schritt verwenden!

Qualifier

Qualifier sind wie spezielle Etiketten, die wir auf unsere Variablen setzen. Sie sagen dem Shader, wie er mit diesen Variablen umgehen soll. Hier sind die wichtigsten:

Qualifier Beschreibung
attribute Eingewerte, die pro Vertex ändern
uniform Eingewerte, die für alle Vertices konstant bleiben
varying Werte, die vom Vertex-Shader zum Fragment-Shader übergeben werden

Vertex Shader

Der Vertex Shader ist wie das Skelett unseres 3D-Modells. Er berechnet, wo jeder Punkt (Vertex) unseres Modells auf dem Bildschirm sein sollte. Hier ist ein einfacher Vertex Shader:

attribute vec3 aVertexPosition;
uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;

void main(void) {
gl_Position = uProjectionMatrix * uModelViewMatrix * vec4(aVertexPosition, 1.0);
}

Lassen Sie uns das aufschlüsseln:

  1. Wir deklarieren ein attribute namens aVertexPosition - dies ist die Position unseres Vertex.
  2. Wir haben zwei uniform Matrizen - diese helfen uns, unser 3D-Modell zu positionieren und auf einen 2D-Bildschirm zu projezieren.
  3. In der main-Funktion berechnen wir die endgültige Position unseres Vertex.

Fragment Shader

Wenn der Vertex Shader das Skelett ist, dann ist der Fragment Shader die Haut. Er entscheidet die Farbe jedes Pixels. Hier ist ein einfacher Fragment Shader:

precision mediump float;

void main(void) {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}

Dieser Shader malt alles rot! Die vec4(1.0, 0.0, 0.0, 1.0) repräsentiert voll Rot, kein Grün, kein Blau und volle Deckkraft.

Speichern und Kompilieren der Shader-Programme

Jetzt, wo wir unsere Shaders geschrieben haben, müssen wir WebGL Bescheid sagen. Hier ist, wie wir das in JavaScript machen:

function getShader(gl, id) {
const shaderScript = document.getElementById(id);
if (!shaderScript) return null;

const str = shaderScript.text;
let shader;

if (shaderScript.type === "x-shader/x-fragment") {
shader = gl.createShader(gl.FRAGMENT_SHADER);
} else if (shaderScript.type === "x-shader/x-vertex") {
shader = gl.createShader(gl.VERTEX_SHADER);
} else {
return null;
}

gl.shaderSource(shader, str);
gl.compileShader(shader);

if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}

return shader;
}

Diese Funktion macht einige Dinge:

  1. Sie findet unseren Shader-Code im HTML-Dokument.
  2. Sie erstellt einen Shader der richtigen Art (Vertex oder Fragment).
  3. Sie komiliert den Shader und überprüft auf Fehler.

Kombiniertes Programm

Schließlich müssen wir unsere Vertex- und Fragment-Shaders zu einem Programm kombinieren:

const shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
gl.linkProgram(shaderProgram);

if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
alert("Konnte Shaders nicht initialisieren");
}

gl.useProgram(shaderProgram);

Dieser Code erstellt ein Programm, hängt unsere Shaders an, verlinkt das Programm und sagt WebGL, es zu verwenden.

Und das war's! Sie haben gerade Ihre ersten Schritte in die Welt der WebGL Shaders gemacht. Erinnern Sie sich daran, dass wie beim Lernen jeder neuen Sprache, Übung erforderlich ist. Lassen Sie sich nicht entmutigen, wenn es nicht sofort klappt – experimentieren Sie weiter und bald werden Sie erstaunliche 3D-Grafiken in Ihrem Webbrowser erstellen!

In meinen Jahren des Unterrichtens habe ich unzählige Schüler von kompletten Anfängern zu Shader-Zaubern werden sehen. Einige meiner Schüler haben sogar diese Fähigkeiten verwendet, um für ihre Abschlussarbeiten virtuelle Kunstaustellungen zu erstellen – stellen Sie sich vor, durch ein 3D-Museum im Webbrowser zu gehen!

Was werden Sie mit Ihren neuen Shader-Fähigkeiten erstellen? Die einzige Grenze ist Ihre Vorstellungskraft! Frohes Coden, zukünftige Grafik-Gurus!

Credits: Image by storyset