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

WebGLRenderingContext.framebufferRenderbuffer()

Methode

Hängt ein <code>WebGLRenderbuffer</code> als Farb-, Tiefen- oder Stencil-Anhang an den aktuell gebundenen <code>WebGLFramebuffer</code>.

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

Signatur

WebGLRenderingContext.prototype.framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer)

Beschreibung

Mit framebufferRenderbuffer() verbindest du ein Renderbuffer-Objekt mit einem Anhangspunkt (attachment point) des Framebuffers, der gerade an target gebunden ist. Renderbuffer sind Speicherbereiche, die für das Offscreen-Rendering optimiert sind. Anders als Texturen kann man sie im Shader aber nicht als Sampler auslesen.

Typischerweise nutzt man diese Methode für den Tiefen- und Stencil-Puffer eines Framebuffers, der in eine Textur rendert. Die Farbe landet dann in einer Textur (über framebufferTexture2D()), die Tiefeninformation in einem Renderbuffer. In WebGL 2 kommen dazu Multisample-Renderbuffer (renderbufferStorageMultisample()), die man anschließend mit blitFramebuffer() auflöst.

Zuerst musst du den Framebuffer mit bindFramebuffer() binden und den Speicher des Renderbuffers mit renderbufferStorage() anlegen. Das interne Format muss zum Anhangspunkt passen, zum Beispiel DEPTH_COMPONENT16 für DEPTH_ATTACHMENT. Danach solltest du mit checkFramebufferStatus() prüfen, ob der Framebuffer vollständig ist.

Übergibst du für renderbuffer den Wert null, löst du den aktuellen Anhang an diesem Anhangspunkt.

Parameter

Name Typ Default Beschreibung
$target Pflicht GLenum Ziel, an das der Framebuffer gebunden ist. WebGL 1: nur gl.FRAMEBUFFER. WebGL 2 zusätzlich gl.DRAW_FRAMEBUFFER und gl.READ_FRAMEBUFFER.
$attachment Pflicht GLenum Anhangspunkt: gl.COLOR_ATTACHMENT0, gl.DEPTH_ATTACHMENT, gl.STENCIL_ATTACHMENT oder gl.DEPTH_STENCIL_ATTACHMENT. In WebGL 2 zusätzlich COLOR_ATTACHMENT1 bis COLOR_ATTACHMENT15. In WebGL 1 gibt es weitere Farb-Anhänge nur mit der Erweiterung WEBGL_draw_buffers.
$renderbuffertarget Pflicht GLenum Muss gl.RENDERBUFFER sein.
$renderbuffer Pflicht WebGLRenderbuffer | null Das Renderbuffer-Objekt, das angehängt wird. Mit null löst du den bestehenden Anhang.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Fehler meldet die Methode über gl.getError(), zum Beispiel INVALID_ENUM oder INVALID_OPERATION.

Beispiele

Tiefenpuffer für Render-to-Texture anhängen

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const width = 512, height = 512;

// Farbziel: Textur
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);

// Tiefenziel: Renderbuffer
const depthRb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, depthRb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);

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 vollständig' : `Fehler: 0x${status.toString(16)}`);

gl.bindFramebuffer(gl.FRAMEBUFFER, null);
Framebuffer vollständig

Kombinierter Tiefen-/Stencil-Puffer (WebGL 1)

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

const dsRb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, dsRb);
// In WebGL 1 ist DEPTH_STENCIL das passende Format
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL, 256, 256);

const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);

const colorRb = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, colorRb);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 256, 256);

gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorRb);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, dsRb);

console.log(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE);
true

Multisampling-Kantenglättung mit WebGL 2 und blitFramebuffer

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2', { antialias: false });
const { width, height } = canvas;
const samples = Math.min(4, gl.getParameter(gl.MAX_SAMPLES));

const msColor = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, msColor);
gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.RGBA8, width, height);

const msDepth = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, msDepth);
gl.renderbufferStorageMultisample(gl.RENDERBUFFER, samples, gl.DEPTH_COMPONENT24, width, height);

const msFbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, msFbo);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, msColor);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, msDepth);

// ... Szene in msFbo zeichnen ...
gl.clearColor(0.1, 0.2, 0.3, 1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);

// Auf den Canvas auflösen
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, msFbo);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, null);
gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, gl.COLOR_BUFFER_BIT, gl.NEAREST);