Signatur
Beschreibung
createRenderbuffer() legt ein leeres Renderbuffer-Objekt auf der GPU an. Ein Renderbuffer ist ein Speicherbereich, in den gerendert wird. Anders als eine Textur kann man ihn im Shader nicht direkt auslesen. Man nutzt ihn vor allem als Tiefen- oder Stencil-Puffer für einen eigenen Framebuffer (Offscreen-Rendering, Post-Processing, Shadow-Maps mit Farbtextur usw.).
Nach dem Anlegen hat der Renderbuffer noch keinen Speicher. Der übliche Ablauf ist:
gl.bindRenderbuffer(gl.RENDERBUFFER, rb)– Renderbuffer bindengl.renderbufferStorage(gl.RENDERBUFFER, format, width, height)– Speicher mit Format und Größe reservierengl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, rb)– an einen Framebuffer anhängen
Renderbuffer eignen sich immer dann, wenn das Ergebnis nicht als Textur weiterverarbeitet werden muss. In WebGL 2 kommt Multisampling über renderbufferStorageMultisample() dazu. So lässt sich Kantenglättung (Anti-Aliasing) in eigenen Framebuffern umsetzen.
Rückgabewert
WebGLRenderbuffer-Objekt. Ist der Kontext verloren gegangen (context lost), wird null zurückgegeben.Beispiele
Tiefenpuffer für einen Offscreen-Framebuffer
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const width = 512, height = 512;
// Farbtextur als Render-Ziel
const colorTex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, colorTex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
// Renderbuffer als Tiefenpuffer
const depthRb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthRb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
// Framebuffer zusammenbauen
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, depthRb);
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
console.log(status === gl.FRAMEBUFFER_COMPLETE ? 'Framebuffer bereit' : `Fehler: 0x${status.toString(16)}`);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
Kombinierter Tiefen-/Stencil-Puffer
const gl = document.createElement('canvas').getContext('webgl');
const depthStencil = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthStencil);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, 256, 256);
console.log(gl.isRenderbuffer(depthStencil));
console.log(gl.getRenderbufferParameter(gl.RENDERBUFFER, gl.RENDERBUFFER_WIDTH));
Multisampling-Renderbuffer in WebGL 2 und Aufräumen
const gl = document.createElement('canvas').getContext('webgl2');
const w = 800, h = 600;
const samples = Math.min(4, gl.getParameter(gl.MAX_SAMPLES));
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);
// ... hier rendern, danach per gl.blitFramebuffer() auflösen ...
// Ressourcen freigeben, wenn sie nicht mehr gebraucht werden
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(msaaFbo);
gl.deleteRenderbuffer(msaaColor);
console.log(gl.isRenderbuffer(msaaColor));
// Wichtig · Fallstricke
- Kein Speicher ohne
renderbufferStorage(): Ein frisch erzeugter Renderbuffer hat die Größe 0×0. Ein Framebuffer, an dem er hängt, ist dann nicht vollständig (FRAMEBUFFER_INCOMPLETE_ATTACHMENT). - Nicht als Textur lesbar: Brauchst du das Ergebnis später in einem Shader, nimm eine Textur statt eines Renderbuffers. Den Inhalt eines Renderbuffers bekommst du nur über
readPixels()oder (in WebGL 2) überblitFramebuffer(). - Formate in WebGL 1 sind eingeschränkt: Erlaubt sind nur
RGBA4,RGB565,RGB5_A1,DEPTH_COMPONENT16,STENCIL_INDEX8undDEPTH_STENCIL. WebGL 2 bietet zusätzlich z. B.RGBA8,DEPTH24_STENCIL8undDEPTH_COMPONENT32F. - Größenlimit: Breite und Höhe dürfen
gl.getParameter(gl.MAX_RENDERBUFFER_SIZE)nicht überschreiten. - Kontextverlust: Nach
webglcontextlostgibt die Methodenullzurück. Alle Renderbuffer musst du nachwebglcontextrestoredneu anlegen. - Speicherlecks: GPU-Speicher wird nicht zuverlässig von der Garbage Collection freigegeben. Gib Renderbuffer ausdrücklich mit
deleteRenderbuffer()frei, besonders wenn du bei jeder Größenänderung des Canvas neue anlegst. - Die Methode gibt es in allen Browsern mit WebGL-Unterstützung, ebenso in
WebGL2RenderingContext.