Signatur
Beschreibung
blitFramebuffer() überträgt einen rechteckigen Bereich von Farb-, Tiefen- und/oder Stencil-Daten aus dem Framebuffer, der an gl.READ_FRAMEBUFFER gebunden ist, in den Framebuffer, der an gl.DRAW_FRAMEBUFFER gebunden ist. Ist an einem der beiden Ziele null gebunden, wird der Standard-Framebuffer (die Canvas) verwendet.
Typische Anwendungsfälle sind das Auflösen von Multisample-Renderbuffern (MSAA) in eine normale Textur, das Kopieren eines Offscreen-Renderziels auf die Canvas, das Skalieren von Bildern (z. B. Downsampling für Bloom-Effekte) sowie das Spiegeln eines Bildes, indem man die Quell- oder Zielkoordinaten vertauscht (dstY0 > dstY1).
Die Rechtecke werden als halboffene Intervalle angegeben: X0/Y0 sind inklusiv, X1/Y1 exklusiv. Unterscheiden sich Quell- und Zielgröße, wird skaliert – dabei entscheidet filter über Nearest-Neighbor- oder lineare Interpolation. Die Scissor-Box wirkt auf das Ziel, Pixel-Ownership-Tests ebenso; Blending, Depth-Test und Shader spielen dagegen keine Rolle.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $srcX0 Pflicht | GLint | — | Linke X-Koordinate (inklusiv) des Quellrechtecks im Lese-Framebuffer. |
| $srcY0 Pflicht | GLint | — | Untere Y-Koordinate (inklusiv) des Quellrechtecks. Ursprung liegt unten links. |
| $srcX1 Pflicht | GLint | — | Rechte X-Grenze (exklusiv) des Quellrechtecks. |
| $srcY1 Pflicht | GLint | — | Obere Y-Grenze (exklusiv) des Quellrechtecks. |
| $dstX0 Pflicht | GLint | — | Linke X-Koordinate des Zielrechtecks im Zeichen-Framebuffer. |
| $dstY0 Pflicht | GLint | — | Untere Y-Koordinate des Zielrechtecks. |
| $dstX1 Pflicht | GLint | — | Rechte X-Grenze des Zielrechtecks (exklusiv). Ist sie kleiner als dstX0, wird horizontal gespiegelt. |
| $dstY1 Pflicht | GLint | — | Obere Y-Grenze des Zielrechtecks (exklusiv). Ist sie kleiner als dstY0, wird vertikal gespiegelt. |
| $mask Pflicht | GLbitfield | — | Bitweise ODER-Verknüpfung aus gl.COLOR_BUFFER_BIT, gl.DEPTH_BUFFER_BIT und gl.STENCIL_BUFFER_BIT – legt fest, welche Puffer kopiert werden. |
| $filter Pflicht | GLenum | — | Interpolation bei Skalierung: gl.NEAREST oder gl.LINEAR. LINEAR ist nur für den Farbpuffer erlaubt. |
Rückgabewert
undefined). Fehler werden über gl.getError() gemeldet.Beispiele
MSAA-Renderbuffer in eine Textur auflösen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2');
const { width, height } = canvas;
// Multisample-Framebuffer (4x MSAA)
const msaaFbo = gl.createFramebuffer();
const msaaRb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, msaaRb);
gl.renderbufferStorageMultisample(gl.RENDERBUFFER, 4, gl.RGBA8, width, height);
gl.bindFramebuffer(gl.FRAMEBUFFER, msaaFbo);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaRb);
// Ziel: normale Textur
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA8, width, height);
const resolveFbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, resolveFbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
// ... Szene in msaaFbo rendern ...
gl.bindFramebuffer(gl.FRAMEBUFFER, msaaFbo);
gl.clearColor(0.2, 0.4, 0.8, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// Auflösen: Größen müssen identisch sein
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFbo);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, resolveFbo);
gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height,
gl.COLOR_BUFFER_BIT, gl.NEAREST);
console.log(gl.getError() === gl.NO_ERROR);
Offscreen-Bild skaliert auf die Canvas kopieren
// Niedrig aufgelöstes Renderziel (z. B. Retro-Look) hochskalieren
const lowW = 320, lowH = 180;
const lowFbo = gl.createFramebuffer();
const lowRb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, lowRb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA8, lowW, lowH);
gl.bindFramebuffer(gl.FRAMEBUFFER, lowFbo);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, lowRb);
// ... in lowFbo rendern ...
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, lowFbo);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null); // null = Canvas
gl.blitFramebuffer(
0, 0, lowW, lowH,
0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight,
gl.COLOR_BUFFER_BIT,
gl.NEAREST // pixelig; gl.LINEAR für weiche Skalierung
);
Bild beim Kopieren vertikal spiegeln
const w = gl.drawingBufferWidth;
const h = gl.drawingBufferHeight;
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, lowFbo);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
// dstY0 und dstY1 vertauscht => Bild steht auf dem Kopf
gl.blitFramebuffer(0, 0, lowW, lowH, 0, h, w, 0,
gl.COLOR_BUFFER_BIT, gl.LINEAR);