Signatur
Beschreibung
Ein WebGLRenderbuffer ist ein undurchsichtiges Handle auf einen GPU-Speicherbereich, der ein einzelnes 2D-Bild enthält. Anders als eine WebGLTexture kann ein Renderbuffer nicht in Shadern gesampelt werden. Er dient ausschließlich als Anhang (Attachment) eines WebGLFramebuffer, typischerweise als Tiefen-, Stencil- oder Multisample-Farbpuffer beim Offscreen-Rendering.
Das Interface besitzt weder eigene Eigenschaften noch Methoden. Instanzen erzeugt man nicht mit new, sondern über gl.createRenderbuffer(). Bearbeitet wird der Puffer mit Methoden des Rendering-Kontexts: gl.bindRenderbuffer(), gl.renderbufferStorage() (bzw. in WebGL 2 gl.renderbufferStorageMultisample()), gl.framebufferRenderbuffer(), gl.getRenderbufferParameter(), gl.isRenderbuffer() und gl.deleteRenderbuffer().
Typische Einsatzfälle sind:
- Tiefenpuffer für Render-to-Texture: Die Farbe landet in einer Textur, die Tiefe in einem Renderbuffer, weil man sie später nicht auslesen muss.
- MSAA-Offscreen-Rendering (WebGL 2): Man rendert in einen Multisample-Renderbuffer und löst ihn mit
gl.blitFramebuffer()in eine Textur auf. - Pixel-Auslesen mit
gl.readPixels(), etwa für GPU-Picking.
Renderbuffer sind häufig etwas effizienter als Texturen, da der Treiber ein für das Rendern optimiertes internes Speicherformat wählen kann.
Rückgabewert
WebGLRenderingContext.createRenderbuffer() bzw. WebGL2RenderingContext.createRenderbuffer() zurückgegeben. Das Objekt selbst hat keine öffentlichen Eigenschaften oder Methoden.Beispiele
Renderbuffer erzeugen und als Tiefenpuffer anhängen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
// Renderbuffer anlegen (kein new!)
const depthBuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, 512, 512);
// Framebuffer mit Farbtextur + Tiefen-Renderbuffer
const colorTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, colorTex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 512, 512, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, colorTex, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, depthBuffer);
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
console.log(depthBuffer instanceof WebGLRenderbuffer);
console.log(status === gl.FRAMEBUFFER_COMPLETE);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
Parameter eines Renderbuffers abfragen
const gl = document.createElement('canvas').getContext('webgl');
const rb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, rb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 256, 128);
const width = gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH);
const height = gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_HEIGHT);
const format = gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_INTERNAL_FORMAT);
console.log(`${width}x${height}`, format === gl.RGBA4);
console.log(gl.isRenderbuffer(rb));
MSAA-Rendering mit Multisample-Renderbuffer (WebGL 2)
const gl = document.createElement('canvas').getContext('webgl2');
const [w, h] = [800, 600];
const samples = Math.min(4, gl.getParameter(gl.MAX_SAMPLES));
// Multisample-Farbpuffer
const msaaColor = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, msaaColor);
gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.RGBA8, w, h);
const msaaFbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, msaaFbo);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msaaColor);
gl.clearColor(0.2, 0.4, 0.8, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
// ... hier Szene zeichnen ...
// Auflösen in den Standard-Framebuffer (Canvas)
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, msaaFbo);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
gl.blitFramebuffer(0, 0, w, h, 0, 0, w, h, gl.COLOR_BUFFER_BIT, gl.NEAREST);
// Aufräumen, wenn nicht mehr benötigt
gl.deleteFramebuffer(msaaFbo);
gl.deleteRenderbuffer(msaaColor);
console.log(gl.isRenderbuffer(msaaColor));
// Wichtig · Fallstricke
- Kein Konstruktor:
new WebGLRenderbuffer()wirft einenTypeError. Immergl.createRenderbuffer()verwenden. - Nicht in Shadern lesbar: Wenn du das Ergebnis später als Textur samplen willst (z. B. Shadow Mapping), nimm eine
WebGLTexturestatt eines Renderbuffers. - Kontextgebunden: Ein Renderbuffer gehört genau zu dem Kontext, der ihn erzeugt hat. Nutzt man ihn in einem anderen Kontext, entsteht
INVALID_OPERATION. Nach einemwebglcontextlost-Ereignis werden alle Renderbuffer ungültig und müssen neu angelegt werden. - Formate: WebGL 1 unterstützt nur
RGBA4,RGB565,RGB5_A1,DEPTH_COMPONENT16,STENCIL_INDEX8undDEPTH_STENCIL. WebGL 2 bietet sized formats wieRGBA8,DEPTH24_STENCIL8und Multisampling. - Größenlimit: Breite und Höhe dürfen
gl.getParameter(gl.MAX_RENDERBUFFER_SIZE)nicht überschreiten. Nach dem Anhängen immer mitgl.checkFramebufferStatus()prüfen. - Speicher: Die Garbage Collection gibt GPU-Speicher nicht zuverlässig frei. Nicht mehr benötigte Puffer deshalb explizit mit
gl.deleteRenderbuffer()löschen, vor allem beim Ändern der Canvas-Größe. - Die Browser-Unterstützung ist umfassend (alle modernen Desktop- und Mobilbrowser). In Workern steht das Interface über
OffscreenCanvaszur Verfügung.