Signatur
Beschreibung
createShader() ist der erste Schritt jeder WebGL-Shader-Pipeline. Die Methode legt auf der GPU-Seite ein neues, noch leeres Shader-Objekt an. Anschließend übergibt man den GLSL-Quelltext mit gl.shaderSource(), kompiliert ihn mit gl.compileShader() und hängt den fertigen Shader per gl.attachShader() an ein WebGLProgram.
Ein lauffähiges Programm braucht immer genau einen Vertex-Shader (gl.VERTEX_SHADER), der die Positionen der Eckpunkte berechnet, und einen Fragment-Shader (gl.FRAGMENT_SHADER), der die Farbe jedes Pixels bestimmt. Beide werden jeweils mit einem eigenen createShader()-Aufruf erzeugt.
Wichtig: createShader() selbst prüft keinen Quelltext. Ob die Kompilierung erfolgreich war, muss man nach compileShader() explizit mit gl.getShaderParameter(shader, gl.COMPILE_STATUS) abfragen; Fehlermeldungen liefert gl.getShaderInfoLog(). Die Methode steht identisch auch in WebGL2RenderingContext zur Verfügung.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | GLenum (number) | Art des Shaders: gl.VERTEX_SHADER (35633) oder gl.FRAGMENT_SHADER (35632). Andere Werte erzeugen den Fehler gl.INVALID_ENUM. |
Rückgabewert
WebGLShader-Objekt. Bei ungültigem type oder verlorenem Kontext (webglcontextlost) wird null zurückgegeben.Beispiele
Vertex- und Fragment-Shader anlegen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
console.log(vertexShader instanceof WebGLShader);
console.log(gl.getShaderParameter(vertexShader, gl.SHADER_TYPE) === gl.VERTEX_SHADER);
Wiederverwendbare Hilfsfunktion mit Fehlerprüfung
const compileShader = (gl, type, source) => {
const shader = gl.createShader(type);
if (!shader) throw new Error('Shader konnte nicht erzeugt werden (Kontext verloren?)');
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(shader);
gl.deleteShader(shader);
throw new Error(`Kompilierfehler: ${log}`);
}
return shader;
};
const gl = document.querySelector('canvas').getContext('webgl');
const vs = compileShader(gl, gl.VERTEX_SHADER, `
attribute vec2 aPosition;
void main() {
gl_Position = vec4(aPosition, 0.0, 1.0);
}
`);
console.log('Vertex-Shader kompiliert:', vs);
Komplettes Programm bauen und Dreieck zeichnen
const gl = document.querySelector('canvas').getContext('webgl');
const make = (type, src) => {
const s = gl.createShader(type);
gl.shaderSource(s, src);
gl.compileShader(s);
if (!gl.getShaderParameter(s, gl.COMPILE_STATUS)) throw new Error(gl.getShaderInfoLog(s));
return s;
};
const vs = make(gl.VERTEX_SHADER, `attribute vec2 p; void main(){ gl_Position = vec4(p, 0.0, 1.0); }`);
const fs = make(gl.FRAGMENT_SHADER, `precision mediump float; void main(){ gl_FragColor = vec4(1.0, 0.4, 0.0, 1.0); }`);
const program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) throw new Error(gl.getProgramInfoLog(program));
// Shader werden nach dem Linken nicht mehr benötigt
gl.deleteShader(vs);
gl.deleteShader(fs);
gl.useProgram(program);
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.8, -0.8, -0.8, 0.8, -0.8]), gl.STATIC_DRAW);
const loc = gl.getAttribLocation(program, 'p');
gl.enableVertexAttribArray(loc);
gl.vertexAttribPointer(loc, 2, gl.FLOAT, false, 0, 0);
gl.drawArrays(gl.TRIANGLES, 0, 3);
// Wichtig · Fallstricke
- Kein automatischer Fehler: Syntaxfehler im GLSL-Code werfen keine JavaScript-Exception. Immer
COMPILE_STATUSprüfen undgetShaderInfoLog()auslesen. - Kontextverlust: Geht der WebGL-Kontext verloren (z. B. GPU-Reset, Tab im Hintergrund auf Mobilgeräten), liefert
createShader()null. Nachwebglcontextrestoredmüssen alle Shader neu erzeugt werden. - Speicher freigeben: Shader belegen GPU-Ressourcen. Nach erfolgreichem
linkProgram()können sie mitgl.deleteShader()markiert werden; sie werden gelöscht, sobald sie von keinem Programm mehr referenziert sind. - GLSL-Version: In WebGL 1 wird GLSL ES 1.00 verwendet; für GLSL ES 3.00 (
#version 300 es, muss die allererste Zeile sein) ist einwebgl2-Kontext nötig. - Präzision: Fragment-Shader in WebGL 1 benötigen eine Präzisionsangabe wie
precision mediump float;, sonst schlägt die Kompilierung fehl. - Kompatibilität: in allen aktuellen Browsern unterstützt; auch in Web Workern über
OffscreenCanvasverfügbar.