Start · Sprachen · JavaScript · Referenz · OES_draw_buffers_indexed.blendFuncSeparateiOES()

OES_draw_buffers_indexed.blendFuncSeparateiOES()

Methode

Legt für einen einzelnen Zeichenpuffer (Draw Buffer) getrennte Blend-Faktoren für RGB- und Alphakomponenten fest.

seit JavaScript WebGL-2-Erweiterung; Chrome/Edge 100+, Firefox 101 Kategorie: webapi

Signatur

OES_draw_buffers_indexed.blendFuncSeparateiOES(buf, srcRGB, dstRGB, srcAlpha, dstAlpha)

Beschreibung

Die Methode blendFuncSeparateiOES() gehört zur WebGL-Erweiterung OES_draw_buffers_indexed. Sie ist die pufferbezogene Variante von WebGLRenderingContext.blendFuncSeparate(): Statt die Blend-Faktoren global für alle Farbanhänge eines Framebuffers zu setzen, gelten sie nur für den über buf angegebenen Zeichenpuffer (gl.COLOR_ATTACHMENT0 + buf bzw. den Eintrag an Position buf in gl.drawBuffers()).

Das ist vor allem beim Multiple Render Targets (MRT)-Rendering nützlich, etwa beim Deferred Shading oder bei Order-Independent Transparency (Weighted Blended OIT). Dort brauchen verschiedene Ausgaben ganz unterschiedliche Mischformeln: Ein Akkumulationspuffer wird zum Beispiel additiv gemischt (ONE, ONE), während ein Revealage-Puffer multiplikativ gemischt wird (ZERO, ONE_MINUS_SRC_ALPHA).

Die Mischung ergibt sich aus Ergebnis = Quelle · srcFaktor ⊕ Ziel · dstFaktor, wobei die Operation ⊕ über blendEquationiOES() bzw. blendEquationSeparateiOES() festgelegt wird. Blending muss dabei für den jeweiligen Puffer mit enableiOES(gl.BLEND, buf) (oder global mit gl.enable(gl.BLEND)) aktiviert sein.

Die Erweiterung ist nur in WebGL-2-Kontexten verfügbar und muss vorher mit gl.getExtension("OES_draw_buffers_indexed") abgerufen werden.

Parameter

Name Typ Default Beschreibung
$buf Pflicht GLuint (number) Index des Zeichenpuffers, für den die Faktoren gelten. Muss kleiner als gl.getParameter(gl.MAX_DRAW_BUFFERS) sein.
$srcRGB Pflicht GLenum (number) Faktor für die RGB-Komponenten der Quellfarbe, z. B. gl.ONE, gl.SRC_ALPHA, gl.ONE_MINUS_DST_ALPHA, gl.CONSTANT_COLOR oder gl.SRC_ALPHA_SATURATE.
$dstRGB Pflicht GLenum (number) Faktor für die RGB-Komponenten der Zielfarbe (bereits im Puffer vorhandener Wert), z. B. gl.ONE_MINUS_SRC_ALPHA.
$srcAlpha Pflicht GLenum (number) Faktor für die Alphakomponente der Quellfarbe.
$dstAlpha Pflicht GLenum (number) Faktor für die Alphakomponente der Zielfarbe.

Rückgabewert

Typ
void
Beschreibung
Kein Rückgabewert (undefined). Fehler werden über gl.getError() gemeldet.

Beispiele

Erweiterung abrufen und Faktoren 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.log("OES_draw_buffers_indexed wird nicht unterstützt");
} else {
  // Blending nur für Zeichenpuffer 0 aktivieren
  ext.enableiOES(gl.BLEND, 0);
  // Klassisches Alpha-Blending für RGB, Alpha additiv akkumulieren
  ext.blendFuncSeparateiOES(
    0,
    gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, // RGB
    gl.ONE, gl.ONE_MINUS_SRC_ALPHA         // Alpha
  );
  console.log(gl.getError() === gl.NO_ERROR ? "OK" : "Fehler");
}
OK

Weighted Blended OIT: zwei Puffer, zwei Mischformeln

const gl = document.createElement("canvas").getContext("webgl2");
const ext = gl.getExtension("OES_draw_buffers_indexed");

// Framebuffer mit zwei Farbanhängen vorbereiten (Texturen hier verkürzt)
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
const makeTex = (format, type) => {
  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  gl.texStorage2D(gl.TEXTURE_2D, 1, format, 256, 256);
  return tex;
};
gl.getExtension("EXT_color_buffer_float");
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, makeTex(gl.RGBA16F), 0);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT1, gl.TEXTURE_2D, makeTex(gl.RGBA8), 0);
gl.drawBuffers([gl.COLOR_ATTACHMENT0, gl.COLOR_ATTACHMENT1]);

gl.enable(gl.BLEND);
// Puffer 0: Akkumulation (additiv)
ext.blendFuncSeparateiOES(0, gl.ONE, gl.ONE, gl.ONE, gl.ONE);
// Puffer 1: Revealage (multiplikativ)
ext.blendFuncSeparateiOES(1, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ZERO, gl.ONE_MINUS_SRC_ALPHA);

// Aktuelle Werte eines Puffers auslesen
console.log(gl.getIndexedParameter(gl.BLEND_SRC_RGB, 1) === gl.ZERO);
true

Zustand zurücksetzen

const gl = document.createElement("canvas").getContext("webgl2");
const ext = gl.getExtension("OES_draw_buffers_indexed");

const resetBlend = (maxBuffers) => {
  for (let i = 0; i < maxBuffers; i++) {
    ext.blendFuncSeparateiOES(i, gl.ONE, gl.ZERO, gl.ONE, gl.ZERO); // Standardwerte
    ext.disableiOES(gl.BLEND, i);
  }
};

resetBlend(gl.getParameter(gl.MAX_DRAW_BUFFERS));
console.log("Blend-Zustand zurückgesetzt");
Blend-Zustand zurückgesetzt

// Wichtig · Fallstricke

  • Nur WebGL 2: In einem webgl-Kontext (WebGL 1) liefert getExtension() immer null. Vor der Nutzung immer auf null prüfen.
  • Globale Aufrufe überschreiben alles: Ein späterer Aufruf von gl.blendFunc() oder gl.blendFuncSeparate() setzt die Faktoren für alle Zeichenpuffer gleichzeitig und verwirft die pufferbezogenen Einstellungen.
  • INVALID_VALUE, wenn buf ≥ MAX_DRAW_BUFFERS ist; INVALID_ENUM bei ungültigen Faktor-Konstanten.
  • Die gleichzeitige Nutzung von CONSTANT_COLOR und CONSTANT_ALPHA als Quell- und Zielfaktor ist in WebGL unzulässig (INVALID_OPERATION).
  • Integer-Farbformate (z. B. RGBA8UI) werden nicht gemischt – Blending hat dort keine Wirkung.
  • Browser-Unterstützung: Chromium-basierte Browser und Firefox unterstützen die Erweiterung, Safari und manche mobile GPUs nur teilweise. Einen Fallback ohne pufferbezogenes Blending vorsehen.
  • Zum Auslesen des Zustands dient gl.getIndexedParameter(gl.BLEND_SRC_RGB, buf) usw.