Start · Sprachen · JavaScript · Referenz · EXT_float_blend extension

EXT_float_blend extension

Schnittstelle

Die WebGL-Erweiterung <code>EXT_float_blend</code> erlaubt Blending beim Zeichnen in Farbpuffer mit 32-Bit-Gleitkomma-Komponenten (z. B. <code>RGBA32F</code>).

seit JavaScript WebGL 1 und WebGL 2 (Erweiterung); Unterstützung a Kategorie: webapi

Signatur

interface EXT_float_blend

Beschreibung

EXT_float_blend ist eine WebGL-Erweiterung, die sich nur durch ihr Vorhandensein bemerkbar macht: Sie hat keine eigenen Methoden oder Konstanten. Ist sie aktiviert, darf bei eingeschaltetem gl.BLEND in Farb-Anhänge mit 32-Bit-Gleitkommaformat (gl.RGBA32F, gl.RG32F, gl.R32F) gezeichnet werden. Ohne die Erweiterung erzeugt ein solcher Draw-Call den Fehler gl.INVALID_OPERATION, und es wird nichts gezeichnet.

Sie aktivieren die Erweiterung mit gl.getExtension("EXT_float_blend"). Der Aufruf gibt ein (leeres) Erweiterungsobjekt zurück oder null, wenn Browser oder GPU sie nicht unterstützen. Damit Sie überhaupt in 32-Bit-Float-Texturen rendern können, brauchen Sie zusätzlich EXT_color_buffer_float (WebGL 2) bzw. WEBGL_color_buffer_float und OES_texture_float (WebGL 1).

Typische Anwendungsfälle sind HDR-Rendering, additive Akkumulation (z. B. Partikel, Order-Independent Transparency, Lichtakkumulation beim Deferred Shading), GPGPU-Berechnungen und Histogramme, bei denen die Genauigkeit von 16-Bit-Floats (RGBA16F) nicht reicht oder deren Wertebereich überläuft.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Beim Aktivieren über WebGLRenderingContext.getExtension(): der exakte Erweiterungsname "EXT_float_blend".

Rückgabewert

Typ
EXT_float_blend | null
Beschreibung
gl.getExtension("EXT_float_blend") liefert ein Erweiterungsobjekt ohne Methoden und Eigenschaften oder null, wenn die Erweiterung nicht verfügbar ist. Schon der Aufruf aktiviert die Erweiterung.

Beispiele

Unterstützung prüfen und Erweiterung aktivieren

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

// Rendern in 32-Bit-Float-Puffer ermöglichen
const colorFloat = gl.getExtension("EXT_color_buffer_float");
// Blending für diese Puffer erlauben
const floatBlend = gl.getExtension("EXT_float_blend");

console.log("Float-Rendering:", !!colorFloat);
console.log("Float-Blending:", !!floatBlend);
console.log(gl.getSupportedExtensions().includes("EXT_float_blend"));
Float-Rendering: true Float-Blending: true true

Additive Akkumulation in einen RGBA32F-Framebuffer (WebGL 2)

const gl = document.querySelector("canvas").getContext("webgl2");

if (!gl.getExtension("EXT_color_buffer_float") || !gl.getExtension("EXT_float_blend")) {
  throw new Error("32-Bit-Float-Blending wird nicht unterstützt");
}

const width = 512, height = 512;
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, width, height);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);

const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
console.log(gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE);

// Additives Blending: jeder Draw-Call addiert seine Werte
gl.viewport(0, 0, width, height);
gl.clearColor(0, 0, 0, 0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.enable(gl.BLEND);
gl.blendFunc(gl.ONE, gl.ONE);

// ... hier Shader-Programm binden und gl.drawArrays(...) aufrufen
console.log(gl.getError() === gl.NO_ERROR);
true true

Fallback auf RGBA16F, wenn Float32-Blending fehlt

const chooseAccumulationFormat = (gl) => {
  const hasFloat32 = gl.getExtension("EXT_color_buffer_float") && gl.getExtension("EXT_float_blend");
  if (hasFloat32) return { internalFormat: gl.RGBA32F, label: "RGBA32F" };
  // RGBA16F ist mit EXT_color_buffer_float (bzw. _half_float) auch ohne EXT_float_blend blendbar
  return { internalFormat: gl.RGBA16F, label: "RGBA16F (Fallback)" };
};

const gl = document.createElement("canvas").getContext("webgl2");
const format = chooseAccumulationFormat(gl);
console.log(`Akkumulationspuffer: ${format.label}`);
Akkumulationspuffer: RGBA32F

// Wichtig · Fallstricke

  • Kein INVALID_OPERATION übersehen: Ohne aktivierte Erweiterung schlägt jeder Draw-Call mit eingeschaltetem gl.BLEND auf einen 32-Bit-Float-Anhang fehl. Das passiert still, nur gl.getError() zeigt es an. Aktivieren Sie die Erweiterung daher immer ausdrücklich, auch wenn sie in der Liste von getSupportedExtensions() steht.
  • Nur 32-Bit-Formate: Blending in 16-Bit-Float-Puffer (RGBA16F) funktioniert schon mit EXT_color_buffer_float bzw. EXT_color_buffer_half_float. Dafür brauchen Sie EXT_float_blend nicht.
  • Abhängigkeiten: Die Erweiterung ist nur zusammen mit einer Erweiterung sinnvoll, die das Rendern in Float-Puffer erlaubt (EXT_color_buffer_float in WebGL 2, WEBGL_color_buffer_float in WebGL 1).
  • Kompatibilität: Aktuelle Desktop-Browser (Chrome, Edge, Firefox, Safari) unterstützen sie in der Regel. Auf mobilen GPUs fehlt sie aber häufig, weil deren Hardware kein Float32-Blending kann. Planen Sie immer einen Fallback ein, etwa auf RGBA16F oder Ping-Pong-Rendering ohne Blending.
  • Leistung: 32-Bit-Float-Puffer brauchen doppelt so viel Speicher und Bandbreite wie 16-Bit-Puffer. Nutzen Sie sie nur, wenn Sie die Genauigkeit wirklich brauchen.