Signatur
Beschreibung
OES_fbo_render_mipmap ist eine Erweiterung der WebGL API. In reinem WebGL 1 muss der Parameter level von WebGLRenderingContext.framebufferTexture2D() immer 0 sein, sonst wird der Fehler INVALID_VALUE ausgelöst. Ist die Erweiterung aktiviert, darf level jede gültige Mipmap-Ebene der Textur angeben. So lässt sich direkt in kleinere Mipmap-Stufen rendern.
Die Erweiterung stellt keine eigenen Methoden oder Konstanten bereit. Das zurückgegebene Objekt dient nur als Nachweis, dass die Erweiterung aktiv ist. Sie wird über gl.getExtension("OES_fbo_render_mipmap") aktiviert. Erst danach gilt das erweiterte Verhalten von framebufferTexture2D().
Typische Anwendungsfälle:
- eigene Mipmap-Erzeugung mit Filtern, die besser sind als bei
generateMipmap()(z. B. Gauß- oder Kaiser-Filter), - Bloom- und Weichzeichner-Ketten, bei denen jede Stufe in eine kleinere Mip-Ebene geschrieben wird,
- vorgefilterte Umgebungs-Maps für PBR, bei denen jede Rauheitsstufe einer Mip-Ebene entspricht,
- Hierarchical-Z- bzw. Tiefenpyramiden für Occlusion Culling.
In WebGL 2 ist diese Funktion fester Bestandteil der API. Dort steht die Erweiterung nicht zur Verfügung, weil sie nicht nötig ist.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Wird an gl.getExtension() übergeben und muss genau "OES_fbo_render_mipmap" lauten. |
Rückgabewert
getExtension() gibt ein Erweiterungsobjekt ohne eigene Methoden zurück, wenn die Erweiterung unterstützt wird. Andernfalls ist der Rückgabewert null.Beispiele
Erweiterung aktivieren und Unterstützung prüfen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const ext = gl.getExtension('OES_fbo_render_mipmap');
if (ext) {
console.log('Rendern in Mipmap-Ebenen möglich');
} else {
console.log('Nicht unterstützt – nur Ebene 0 als Render-Ziel');
}
In Mip-Ebene 1 einer Textur rendern (WebGL 1)
const gl = document.createElement('canvas').getContext('webgl');
if (!gl.getExtension('OES_fbo_render_mipmap')) {
throw new Error('OES_fbo_render_mipmap fehlt');
}
const size = 256; // Zweierpotenz ist für Mipmaps in WebGL 1 Pflicht
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// Speicher für alle Mip-Ebenen anlegen
for (let level = 0, s = size; s >= 1; level++, s >>= 1) {
gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, s, s, 0,
gl.RGBA, gl.UNSIGNED_BYTE, null);
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
// level = 1 ist erst durch die Erweiterung erlaubt
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D, tex, 1);
const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
console.log(status === gl.FRAMEBUFFER_COMPLETE);
gl.viewport(0, 0, size >> 1, size >> 1); // Größe von Ebene 1: 128×128
gl.clearColor(1, 0, 0, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
Hilfsfunktion für WebGL 1 und WebGL 2
const canRenderToMipLevels = (gl) => {
if (typeof WebGL2RenderingContext !== 'undefined' &&
gl instanceof WebGL2RenderingContext) {
return true; // in WebGL 2 fest eingebaut
}
return gl.getExtension('OES_fbo_render_mipmap') !== null;
};
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2') ?? canvas.getContext('webgl');
console.log('Mip-Rendering:', canRenderToMipLevels(gl));
Fehlerverhalten ohne Erweiterung
const gl = document.createElement('canvas').getContext('webgl');
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 64, 64, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texImage2D(gl.TEXTURE_2D, 1, gl.RGBA, 32, 32, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, gl.createFramebuffer());
// Erweiterung NICHT aktiviert
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 1);
console.log(gl.getError() === gl.INVALID_VALUE);
// Wichtig · Fallstricke
- Erst aktivieren, dann nutzen: Die Erweiterung zu unterstützen reicht nicht. Sie muss vorher mit
getExtension()aktiviert worden sein, sonst führtlevel > 0zuINVALID_VALUE. - Nur WebGL 1: In einem
WebGL2RenderingContextgibtgetExtension("OES_fbo_render_mipmap")nullzurück, obwohl das Verhalten dort standardmäßig verfügbar ist. - Feedback-Schleifen: In WebGL 1 gibt es kein
TEXTURE_BASE_LEVELund keinTEXTURE_MAX_LEVEL. Wenn eine Textur im Shader gelesen wird, während man in eine ihrer Mip-Ebenen rendert, meldet WebGL eine Feedback-Schleife. Die Folge istINVALID_OPERATIONbeim Zeichnen. In der Praxis liest man deshalb aus einer zweiten Textur und wechselt zwischen beiden ab („Ping-Pong“). Alternativ nutzt man WebGL 2 mit eingeschränktem Ebenen-Bereich. - Zweierpotenzen: Mipmaps setzen in WebGL 1 Texturen voraus, deren Seitenlängen Zweierpotenzen sind. Außerdem muss für die angehängte Ebene ein Bild mit passender Größe angelegt sein. Das prüft man mit
checkFramebufferStatus(). - Viewport anpassen: Der Viewport muss zur Größe der jeweiligen Mip-Ebene passen, also
size >> level. Sonst wird nur ein Teil gerendert. - Kompatibilität: Die Unterstützung hängt von Browser und GPU-Treiber ab und ist nicht überall vorhanden. Deshalb immer auf
nullprüfen und einen Ausweg vorsehen, z. B.generateMipmap()oder separate Texturen je Stufe.