Signatur
Beschreibung
Die Eigenschaft drawingBufferHeight gibt die tatsächliche Höhe des Zeichenpuffers in Pixeln an, in den WebGL rendert. Normalerweise entspricht sie dem Attribut canvas.height. Der Browser darf aber einen kleineren Puffer anlegen, wenn die gewünschte Größe die Grenzen der Grafikhardware überschreitet (etwa MAX_RENDERBUFFER_SIZE oder MAX_VIEWPORT_DIMS) oder wenn nicht genug Grafikspeicher frei ist.
Deshalb solltest du für gl.viewport(), gl.readPixels(), gl.scissor() und Berechnungen des Seitenverhältnisses immer drawingBufferWidth/drawingBufferHeight verwenden statt canvas.width/canvas.height. So passt die Darstellung auch dann, wenn der Puffer stillschweigend verkleinert wurde.
Der Wert ändert sich nur, wenn die Canvas-Attribute width bzw. height gesetzt werden. Die CSS-Größe des Elements (clientHeight) spielt keine Rolle. Die Eigenschaft gibt es auch in WebGL2RenderingContext.
Rückgabewert
GLsizei) mit der Höhe des Zeichenpuffers in Pixeln. Ist der Kontext verloren gegangen, wird in der Regel 0 zurückgegeben.Beispiele
Puffergröße auslesen und mit dem Canvas vergleichen
const canvas = document.createElement('canvas');
canvas.width = 800;
canvas.height = 600;
const gl = canvas.getContext('webgl');
console.log(gl.drawingBufferWidth, gl.drawingBufferHeight);
if (gl.drawingBufferHeight !== canvas.height) {
console.warn('Zeichenpuffer wurde vom Browser verkleinert!');
}
Viewport korrekt setzen bei hochauflösenden Displays
const canvas = document.querySelector('#scene');
const gl = canvas.getContext('webgl2') ?? canvas.getContext('webgl');
const resize = () => {
const dpr = window.devicePixelRatio || 1;
canvas.width = Math.round(canvas.clientWidth * dpr);
canvas.height = Math.round(canvas.clientHeight * dpr);
// Tatsächliche Puffergröße verwenden, nicht canvas.width/height
gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight);
};
window.addEventListener('resize', resize);
resize();
Seitenverhältnis für die Projektionsmatrix
const gl = document.querySelector('canvas').getContext('webgl');
const aspect = gl.drawingBufferWidth / gl.drawingBufferHeight;
const fov = Math.PI / 4;
const f = 1 / Math.tan(fov / 2);
const near = 0.1, far = 100;
// Perspektivische Projektionsmatrix (spaltenweise)
const projection = new Float32Array([
f / aspect, 0, 0, 0,
0, f, 0, 0,
0, 0, (far + near) / (near - far), -1,
0, 0, (2 * far * near) / (near - far), 0
]);
console.log('Aspect:', aspect.toFixed(3));
Gesamten Puffer per readPixels auslesen
const gl = document.querySelector('canvas').getContext('webgl', { preserveDrawingBuffer: true });
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
const w = gl.drawingBufferWidth;
const h = gl.drawingBufferHeight;
const pixels = new Uint8Array(w * h * 4);
gl.readPixels(0, 0, w, h, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
console.log(pixels.slice(0, 4));
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung an
gl.drawingBufferHeightwird ignoriert (im Strict Mode gibt es einenTypeError). Die Größe änderst du nur übercanvas.height. - Kann kleiner sein als
canvas.height: Bei sehr großen Canvas-Elementen (z. B. 8K mit hohemdevicePixelRatio) verkleinert der Browser den Puffer ohne Fehlermeldung. Wer dann mitcanvas.heightrechnet, bekommt verzerrte oder abgeschnittene Bilder. - Nicht die CSS-Größe:
clientHeightund die CSS-Höhe beeinflussen den Wert nicht. Sie bestimmen nur die Skalierung bei der Anzeige. - Kontextverlust: Nach einem
webglcontextlost-Ereignis kann der Wert0sein. - In
OffscreenCanvas-Kontexten gibt es die Eigenschaft ebenfalls. Unterstützt wird sie in allen Browsern mit WebGL 1 und WebGL 2. - Für den Farbraum oder das Pixelformat gibt es eigene Eigenschaften:
drawingBufferColorSpaceund (in neueren Browsern)drawingBufferFormat.