Signatur
Beschreibung
Mit blendFunc() steuerst du, wie die Farbe eines neu gezeichneten Fragments (Quelle) mit der Farbe verrechnet wird, die schon im Framebuffer steht (Ziel). Standardmäßig rechnet WebGL Ergebnis = Quelle × sfactor + Ziel × dfactor. Den Operator (Addition, Subtraktion …) legt blendEquation() fest.
Wichtige Anwendungsfälle sind Transparenz (klassisch SRC_ALPHA, ONE_MINUS_SRC_ALPHA), additives Blending für Partikel, Feuer oder Leuchteffekte (SRC_ALPHA, ONE bzw. ONE, ONE) und vormultipliziertes Alpha (ONE, ONE_MINUS_SRC_ALPHA).
Blending wirkt nur, wenn es vorher mit gl.enable(gl.BLEND) eingeschaltet wurde. Die Einstellung gilt global für den Kontext und bleibt so lange bestehen, bis du sie wieder änderst. Willst du Farb- und Alphakanal getrennt behandeln, nimmst du blendFuncSeparate().
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $sfactor | GLenum | gl.ONE | Faktor für die Quellfarbe. Möglich sind ZERO, ONE, SRC_COLOR, ONE_MINUS_SRC_COLOR, DST_COLOR, ONE_MINUS_DST_COLOR, SRC_ALPHA, ONE_MINUS_SRC_ALPHA, DST_ALPHA, ONE_MINUS_DST_ALPHA, CONSTANT_COLOR, ONE_MINUS_CONSTANT_COLOR, CONSTANT_ALPHA, ONE_MINUS_CONSTANT_ALPHA und SRC_ALPHA_SATURATE. |
| $dfactor | GLenum | gl.ZERO | Faktor für die Zielfarbe im Framebuffer. Erlaubt sind dieselben Konstanten wie bei sfactor, außer SRC_ALPHA_SATURATE, das in WebGL 1 nur als Quellfaktor gültig ist. |
Rückgabewert
undefined). Bei ungültigen Werten setzt WebGL einen Fehler, den du mit gl.getError() abfragen kannst.Beispiele
Klassische Alpha-Transparenz
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// Blending einschalten und Standard-Transparenz setzen
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
// Zuerst die undurchsichtigen Objekte zeichnen,
// danach die transparenten von hinten nach vorne
console.log(gl.getParameter(gl.BLEND_SRC_RGB) === gl.SRC_ALPHA);
Additives Blending für Partikeleffekte
const gl = document.querySelector('canvas').getContext('webgl');
const drawParticles = (drawCall) => {
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE); // Farben addieren sich -> Leuchten
gl.depthMask(false); // Tiefenpuffer nicht beschreiben
drawCall();
gl.depthMask(true);
// Zustand zurücksetzen
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
};
drawParticles(() => gl.drawArrays(gl.POINTS, 0, 0));
Vormultipliziertes Alpha bei Texturen
const gl = document.querySelector('canvas').getContext('webgl', {
premultipliedAlpha: true
});
// Texturen beim Hochladen vormultiplizieren lassen
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
console.log(gl.getParameter(gl.BLEND_DST_RGB) === gl.ONE_MINUS_SRC_ALPHA);
// Wichtig · Fallstricke
- Ohne
gl.enable(gl.BLEND)passiert nichts. Das ist der häufigste Grund, warum Transparenz „nicht funktioniert“. - Kombinierst du
CONSTANT_COLORbzw.ONE_MINUS_CONSTANT_COLORmitCONSTANT_ALPHAbzw.ONE_MINUS_CONSTANT_ALPHAals Quell- und Zielfaktor, meldet WebGLINVALID_OPERATION. Ungültige Konstanten führen zuINVALID_ENUM. - Transparente Objekte müssen meist von hinten nach vorne sortiert gezeichnet werden. Sonst verwirft der Tiefentest verdeckte Fragmente, bevor sie gemischt werden.
- Ist der Kontext mit
premultipliedAlpha: trueerstellt (Standard) und du nutztSRC_ALPHA, ONE_MINUS_SRC_ALPHAmit nicht vormultiplizierten Farben, können beim Zusammensetzen mit der Seite helle oder dunkle Ränder entstehen. - Seit WebGL 1.0 in allen modernen Browsern verfügbar, ebenso in
WebGL2RenderingContext.