Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext

WebGLRenderingContext

Schnittstelle

Stellt den OpenGL-ES-2.0-basierten 3D-Rendering-Kontext für ein <code>&lt;canvas&gt;</code>-Element bereit – erhältlich über <code>canvas.getContext("webgl")</code>.

seit JavaScript Baseline: alle Browser (WebGL 1.0, seit 2011–2014) Kategorie: webapi

Signatur

interface WebGLRenderingContext

Beschreibung

WebGLRenderingContext ist die zentrale Schnittstelle von WebGL 1.0. Über sie wird die GPU direkt aus JavaScript angesprochen: Sie kompilieren Shader in GLSL ES 1.00, laden Vertex-Daten in Puffer, binden Texturen und lösen Zeichenaufrufe wie drawArrays() oder drawElements() aus. Die API ist sehr nah an OpenGL ES 2.0 angelehnt und arbeitet als Zustandsautomat: Die meisten Aufrufe verändern den aktuell gebundenen Zustand (Programm, Puffer, Textur), statt Objekte direkt zu übergeben.

Ein Objekt dieser Schnittstelle erhalten Sie mit canvas.getContext("webgl") (bzw. OffscreenCanvas.getContext("webgl") im Worker). Ein Konstruktor existiert nicht. Optional lassen sich Kontextattribute wie antialias, alpha, depth, preserveDrawingBuffer oder powerPreference übergeben. Neben den Methoden stellt das Objekt zahlreiche Konstanten bereit, etwa gl.TRIANGLES, gl.ARRAY_BUFFER oder gl.COLOR_BUFFER_BIT.

Sie verwenden WebGL, wenn 2D-Canvas nicht mehr ausreicht: 3D-Szenen, Datenvisualisierungen mit Zehntausenden Punkten, Bildfilter per Fragment-Shader oder Spiele. Für neue Projekte bietet sich meist WebGL2RenderingContext (OpenGL ES 3.0) an, da es breit unterstützt wird; WebGL 1 bleibt der kleinste gemeinsame Nenner. Wer nicht direkt mit der Low-Level-API arbeiten möchte, greift zu Bibliotheken wie Three.js, Babylon.js oder regl.

Wichtige Methodengruppen: Shader/Programme (createShader, shaderSource, compileShader, createProgram, linkProgram, useProgram), Puffer (createBuffer, bindBuffer, bufferData), Attribute/Uniforms (getAttribLocation, vertexAttribPointer, getUniformLocation, uniform*), Texturen (createTexture, texImage2D, texParameteri), Zustand/Zeichnen (viewport, clearColor, clear, enable, drawArrays, drawElements) sowie Erweiterungen (getExtension, getSupportedExtensions).

Parameter

Name Typ Default Beschreibung
$contextType Pflicht "webgl" | "experimental-webgl" Erstes Argument von canvas.getContext(). "webgl" liefert einen WebGLRenderingContext; "experimental-webgl" ist ein veralteter Alias.
$contextAttributes WebGLContextAttributes {} Optionales Objekt mit u. a. alpha (true), depth (true), stencil (false), antialias (true), premultipliedAlpha (true), preserveDrawingBuffer (false), powerPreference ("default", "high-performance", "low-power"), failIfMajorPerformanceCaveat (false).

Rückgabewert

Typ
WebGLRenderingContext | null
Beschreibung
Der Rendering-Kontext oder null, wenn WebGL nicht verfügbar ist (fehlende GPU-Unterstützung, deaktiviert, Blockliste) oder das Canvas bereits einen anderen Kontexttyp besitzt.

Beispiele

Kontext holen und Zeichenfläche einfärben

const canvas = document.querySelector('#scene');
const gl = canvas.getContext('webgl', { antialias: true });

if (!gl) {
  console.error('WebGL wird nicht unterstützt.');
} else {
  gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
  gl.clearColor(0.1, 0.2, 0.3, 1.0); // RGBA 0..1
  gl.clear(gl.COLOR_BUFFER_BIT);
  console.log(gl.getParameter(gl.VERSION));
}
WebGL 1.0 (OpenGL ES 2.0 Chromium)

Farbiges Dreieck mit Vertex- und Fragment-Shader

const gl = document.querySelector('#scene').getContext('webgl');

const vsSource = `
  attribute vec2 aPosition;
  void main() {
    gl_Position = vec4(aPosition, 0.0, 1.0);
  }`;
const fsSource = `
  precision mediump float;
  uniform vec4 uColor;
  void main() {
    gl_FragColor = uColor;
  }`;

const compile = (type, source) => {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    throw new Error(gl.getShaderInfoLog(shader));
  }
  return shader;
};

const program = gl.createProgram();
gl.attachShader(program, compile(gl.VERTEX_SHADER, vsSource));
gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fsSource));
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
  throw new Error(gl.getProgramInfoLog(program));
}
gl.useProgram(program);

// Vertex-Daten in einen Puffer laden
const vertices = new Float32Array([0, 0.8, -0.8, -0.8, 0.8, -0.8]);
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

const aPosition = gl.getAttribLocation(program, 'aPosition');
gl.enableVertexAttribArray(aPosition);
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);

gl.uniform4f(gl.getUniformLocation(program, 'uColor'), 1.0, 0.5, 0.0, 1.0);

gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);

Canvas-Größe an Bildschirm anpassen (HiDPI)

const canvas = document.querySelector('#scene');
const gl = canvas.getContext('webgl');

const resize = () => {
  const dpr = window.devicePixelRatio || 1;
  const width = Math.round(canvas.clientWidth * dpr);
  const height = Math.round(canvas.clientHeight * dpr);
  if (canvas.width !== width || canvas.height !== height) {
    canvas.width = width;
    canvas.height = height;
    gl.viewport(0, 0, width, height);
  }
};

const render = () => {
  resize();
  gl.clearColor(0.05, 0.05, 0.1, 1);
  gl.clear(gl.COLOR_BUFFER_BIT);
  requestAnimationFrame(render);
};
requestAnimationFrame(render);

Kontextverlust behandeln und Erweiterung abfragen

const canvas = document.querySelector('#scene');
let gl = canvas.getContext('webgl');

const ext = gl.getExtension('OES_element_index_uint');
console.log('32-Bit-Indizes verfügbar:', ext !== null);

canvas.addEventListener('webglcontextlost', (event) => {
  event.preventDefault(); // Wiederherstellung erlauben
  console.warn('WebGL-Kontext verloren');
});

canvas.addEventListener('webglcontextrestored', () => {
  console.info('Kontext wiederhergestellt – Ressourcen neu anlegen');
  // Shader, Puffer und Texturen hier neu erzeugen
});
32-Bit-Indizes verfügbar: true