Start · Sprachen · JavaScript · Referenz · WebGL2RenderingContext

WebGL2RenderingContext

Schnittstelle

Stellt den auf OpenGL ES 3.0 basierenden WebGL-2-Rendering-Kontext bereit, mit dem man hardwarebeschleunigte 2D-/3D-Grafik auf ein <code>&lt;canvas&gt;</code> zeichnet.

seit JavaScript Baseline: alle modernen Browser (Safari seit 15) Kategorie: webapi

Signatur

interface WebGL2RenderingContext extends WebGL2RenderingContextBase, WebGLRenderingContextBase

Beschreibung

WebGL2RenderingContext ist die zweite Generation der WebGL-API. Einen solchen Kontext bekommt man über canvas.getContext("webgl2") (auch mit OffscreenCanvas in Web Workern). Er enthält alle Funktionen von WebGLRenderingContext (WebGL 1) und ergänzt sie um die Fähigkeiten von OpenGL ES 3.0. Shader werden in GLSL ES 3.00 geschrieben; die erste Zeile im Shader-Quelltext muss dann #version 300 es lauten.

Die wichtigsten Neuerungen gegenüber WebGL 1:

  • Vertex Array Objects (createVertexArray(), bindVertexArray()) sind fest eingebaut – die Erweiterung OES_vertex_array_object entfällt.
  • Instanziertes Zeichnen mit drawArraysInstanced(), drawElementsInstanced() und vertexAttribDivisor().
  • Uniform Buffer Objects (bindBufferBase(), getUniformBlockIndex(), uniformBlockBinding()).
  • 3D-Texturen und Textur-Arrays (texImage3D(), texStorage2D()/texStorage3D()) sowie Sampler-Objekte (createSampler()).
  • Multiple Render Targets mit drawBuffers(), Multisample-Renderbuffer (renderbufferStorageMultisample()) und blitFramebuffer().
  • Transform Feedback, Query-Objekte (z. B. Occlusion Queries) und Sync-Objekte (fenceSync(), clientWaitSync()).
  • Ganzzahlige Attribute und Uniforms, Texturen ohne Zweierpotenz-Größe ohne Einschränkungen bei Mipmaps und Wrapping, viele neue Texturformate.

Man nutzt WebGL 2 für anspruchsvolle 3D-Szenen, Datenvisualisierung, Spiele, Bildverarbeitung und GPU-Berechnungen. Viele Bibliotheken (z. B. Three.js, Babylon.js, PixiJS) verwenden WebGL 2 intern. Für neue Projekte mit Compute-Bedarf lohnt ein Blick auf WebGPU, WebGL 2 bleibt jedoch die am breitesten unterstützte GPU-API im Web.

Der Kontext ist zustandsbehaftet: Gebundene Puffer, Texturen, Programme und VAOs gelten global für alle folgenden Aufrufe. Fehler werden nicht als Ausnahmen geworfen, sondern über gl.getError() abgefragt.

Parameter

Name Typ Default Beschreibung
$contextType Pflicht string Argument für canvas.getContext(): muss "webgl2" sein, um einen WebGL2RenderingContext zu erhalten.
$contextAttributes WebGLContextAttributes {} Optionales Objekt, z. B. { alpha, antialias, depth, stencil, premultipliedAlpha, preserveDrawingBuffer, powerPreference, failIfMajorPerformanceCaveat, desynchronized }.

Rückgabewert

Typ
WebGL2RenderingContext | null
Beschreibung
getContext("webgl2") liefert den Kontext oder null, wenn WebGL 2 nicht verfügbar ist (fehlende Unterstützung, gesperrter Treiber, deaktivierte Hardwarebeschleunigung).

Beispiele

Kontext anlegen mit Fallback auf WebGL 1

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

if (!gl) {
  throw new Error('WebGL wird nicht unterstützt');
}

const isWebGL2 = gl instanceof WebGL2RenderingContext;
console.log('WebGL 2:', isWebGL2);
console.log(gl.getParameter(gl.VERSION));

gl.clearColor(0.1, 0.1, 0.15, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
WebGL 2: true WebGL 2.0 (OpenGL ES 3.0 Chromium)

Dreieck zeichnen mit GLSL ES 3.00 und Vertex Array Object

const gl = document.querySelector('canvas').getContext('webgl2');

const vsSource = `#version 300 es
in vec2 aPosition;
void main() {
  gl_Position = vec4(aPosition, 0.0, 1.0);
}`;

const fsSource = `#version 300 es
precision highp float;
out vec4 fragColor;
void main() {
  fragColor = vec4(1.0, 0.5, 0.2, 1.0);
}`;

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));
}

// VAO speichert die komplette Attribut-Konfiguration
const vao = gl.createVertexArray();
gl.bindVertexArray(vao);

const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0, 0.7, -0.7, -0.7, 0.7, -0.7]), gl.STATIC_DRAW);

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

gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
gl.clearColor(0, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.useProgram(program);
gl.bindVertexArray(vao);
gl.drawArrays(gl.TRIANGLES, 0, 3);

Instanziertes Zeichnen: viele Objekte mit einem Draw-Call

// Annahme: program und vao aus dem vorigen Beispiel,
// der Vertex-Shader hat zusätzlich: in vec2 aOffset;
// und gl_Position = vec4(aPosition * 0.1 + aOffset, 0.0, 1.0);
const count = 100;
const offsets = new Float32Array(count * 2);
for (let i = 0; i < count; i++) {
  offsets[i * 2] = Math.random() * 2 - 1;
  offsets[i * 2 + 1] = Math.random() * 2 - 1;
}

gl.bindVertexArray(vao);
const offsetBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, offsetBuffer);
gl.bufferData(gl.ARRAY_BUFFER, offsets, gl.STATIC_DRAW);

const offsetLoc = gl.getAttribLocation(program, 'aOffset');
gl.enableVertexAttribArray(offsetLoc);
gl.vertexAttribPointer(offsetLoc, 2, gl.FLOAT, false, 0, 0);
gl.vertexAttribDivisor(offsetLoc, 1); // pro Instanz statt pro Vertex

gl.drawArraysInstanced(gl.TRIANGLES, 0, 3, count);
console.log(`${count} Dreiecke in einem Aufruf gezeichnet`);
100 Dreiecke in einem Aufruf gezeichnet

Kontextverlust behandeln

const canvas = document.querySelector('canvas');
let gl = canvas.getContext('webgl2');

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

canvas.addEventListener('webglcontextrestored', () => {
  console.log('Kontext wiederhergestellt – Ressourcen neu anlegen');
  // Shader, Puffer und Texturen hier erneut erzeugen
});

// Zum Testen: Kontextverlust simulieren
const ext = gl.getExtension('WEBGL_lose_context');
ext?.loseContext();
setTimeout(() => ext?.restoreContext(), 1000);
WebGL-Kontext verloren Kontext wiederhergestellt – Ressourcen neu anlegen