Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext.createRenderbuffer()

WebGLRenderingContext.createRenderbuffer()

Methode

Erstellt ein neues <code>WebGLRenderbuffer</code>-Objekt, das als Render-Ziel (Farbe, Tiefe, Stencil) an einen Framebuffer angehängt werden kann.

seit JavaScript WebGL 1.0 – Baseline: alle modernen Browser Kategorie: webapi

Signatur

WebGLRenderingContext.prototype.createRenderbuffer()

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 binden
  • gl.renderbufferStorage(gl.RENDERBUFFER, format, width, height) – Speicher mit Format und Größe reservieren
  • gl.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

Typ
WebGLRenderbuffer | null
Beschreibung
Ein neues 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);
Framebuffer bereit

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));
true 256

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

// 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) über blitFramebuffer().
  • Formate in WebGL 1 sind eingeschränkt: Erlaubt sind nur RGBA4, RGB565, RGB5_A1, DEPTH_COMPONENT16, STENCIL_INDEX8 und DEPTH_STENCIL. WebGL 2 bietet zusätzlich z. B. RGBA8, DEPTH24_STENCIL8 und DEPTH_COMPONENT32F.
  • Größenlimit: Breite und Höhe dürfen gl.getParameter(gl.MAX_RENDERBUFFER_SIZE) nicht überschreiten.
  • Kontextverlust: Nach webglcontextlost gibt die Methode null zurück. Alle Renderbuffer musst du nach webglcontextrestored neu 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.