Signatur
Beschreibung
blendFunciOES() gehört zur WebGL-2-Erweiterung OES_draw_buffers_indexed. Sie macht dasselbe wie WebGL2RenderingContext.blendFunc(), gilt aber nur für den Zeichenpuffer mit dem Index buf. Ohne die Erweiterung wirkt die Mischfunktion immer gleichzeitig auf alle Farbanhänge eines Framebuffers.
Das braucht man vor allem beim Rendern in mehrere Ziele gleichzeitig (Multiple Render Targets, MRT), z. B. beim Deferred Shading oder bei Order-Independent Transparency (OIT). Dort gehört oft zu jedem Farbanhang eine andere Mischgleichung, etwa additiv in einen Akkumulationspuffer und multiplikativ in einen Revealage-Puffer – und das in einem einzigen Draw-Call.
Die Faktoren sind dieselben Konstanten wie bei blendFunc() (gl.ONE, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA usw.). Das Blending muss außerdem für den Puffer eingeschaltet sein, entweder global mit gl.enable(gl.BLEND) oder gezielt mit ext.enableiOES(gl.BLEND, buf). Wenn du Farbe und Alpha getrennt steuern willst, nimm blendFuncSeparateiOES().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $buf Pflicht | number (GLuint) | Index des Zeichenpuffers, für den die Mischfunktion gelten soll. Er muss kleiner als gl.getParameter(gl.MAX_DRAW_BUFFERS) sein, sonst entsteht INVALID_VALUE. |
|
| $sfactor Pflicht | GLenum | Faktor für die Quellfarbe (Fragment-Ausgabe), z. B. gl.ONE, gl.SRC_ALPHA, gl.ZERO, gl.DST_COLOR, gl.CONSTANT_COLOR oder gl.SRC_ALPHA_SATURATE. |
|
| $dfactor Pflicht | GLenum | Faktor für die Zielfarbe (vorhandener Pufferinhalt), z. B. gl.ONE_MINUS_SRC_ALPHA, gl.ONE oder gl.ZERO. |
Rückgabewert
undefined). Fehler meldet WebGL über gl.getError().Beispiele
Erweiterung laden und Alpha-Blending nur für Puffer 0 setzen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
const ext = gl?.getExtension('OES_draw_buffers_indexed');
if (!ext) {
console.warn('OES_draw_buffers_indexed wird nicht unterstützt');
} else {
// Blending nur für Zeichenpuffer 0 einschalten
ext.enableiOES(gl.BLEND, 0);
// Klassisches Alpha-Blending für Puffer 0
ext.blendFunciOES(0, gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
console.log(gl.getIndexedParameter(gl.BLEND_SRC_RGB, 0) === gl.SRC_ALPHA);
}
Weighted Blended OIT: unterschiedliche Mischfunktionen pro Render-Target
const gl = document.createElement('canvas').getContext('webgl2');
const ext = gl.getExtension('OES_draw_buffers_indexed');
gl.getExtension('EXT_color_buffer_float');
// Framebuffer mit zwei Farbanhängen (Akkumulation + Revealage)
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const makeTex = (format, internal, type) => {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, internal, 256, 256, 0, format, type, null);
return tex;
};
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D,
makeTex(gl.RGBA, gl.RGBA16F, gl.HALF_FLOAT), 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D,
makeTex(gl.RED, gl.R16F, gl.HALF_FLOAT), 0);
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);
gl.enable(gl.BLEND);
// Puffer 0: additive Akkumulation
ext.blendFunciOES(0, gl.ONE, gl.ONE);
// Puffer 1: multiplikative Revealage
ext.blendFunciOES(1, gl.ZERO, gl.ONE_MINUS_SRC_COLOR);
console.log('Puffer 1 dst:', gl.getIndexedParameter(gl.BLEND_DST_RGB, 1) === gl.ONE_MINUS_SRC_COLOR);
// ... danach transparente Geometrie in einem Durchgang zeichnen
Zustand nach dem Durchgang zurücksetzen
const gl = document.createElement('canvas').getContext('webgl2');
const ext = gl.getExtension('OES_draw_buffers_indexed');
ext.blendFunciOES(1, gl.ONE, gl.ONE);
// ... zeichnen ...
// Globales blendFunc überschreibt die Werte ALLER Puffer wieder
gl.blendFunc(gl.ONE, gl.ZERO);
console.log(gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1) === gl.ONE);
// Wichtig · Fallstricke
- Nur WebGL 2: Die Erweiterung gibt es ausschließlich über einen
webgl2-Kontext. Prüfe immer, obgetExtension('OES_draw_buffers_indexed')nullzurückgibt. Chromium-Browser und Firefox unterstützen sie, Safari derzeit nicht zuverlässig. Plane deshalb einen Ausweg ein, z. B. mehrere Render-Durchgänge. - Globale Aufrufe wie
gl.blendFunc()odergl.blendFuncSeparate()überschreiben die Einstellungen aller Zeichenpuffer. Die Reihenfolge der Aufrufe ist also wichtig. - Ist
bufgrößer oder gleichMAX_DRAW_BUFFERS, entstehtINVALID_VALUE. Ein ungültiger Faktor erzeugtINVALID_ENUM. - WebGL verbietet,
CONSTANT_COLORundCONSTANT_ALPHA(bzw. derenONE_MINUS_-Varianten) als Quell- und Zielfaktor zu kombinieren (INVALID_OPERATION). - Wenn du in Gleitkomma-Puffer mischst (z. B.
RGBA16F), brauchst du zusätzlichEXT_color_buffer_floatbzw.EXT_float_blendfür 32-Bit-Formate. - Den gesetzten Wert liest du mit
gl.getIndexedParameter(gl.BLEND_SRC_RGB, buf)aus.gl.getParameter()liefert nur den Wert für Puffer 0.