Start · Sprachen · JavaScript · Referenz · OES_texture_float_linear extension

OES_texture_float_linear extension

Schnittstelle

WebGL-Erweiterung, die lineare Filterung (<code>LINEAR</code>, <code>LINEAR_MIPMAP_*</code>) für Texturen mit 32-Bit-Gleitkomma-Pixeln (<code>gl.FLOAT</code>) erlaubt.

seit JavaScript WebGL 1 und WebGL 2 – Baseline: in allen modernen Kategorie: webapi

Signatur

interface OES_texture_float_linear

Beschreibung

OES_texture_float_linear ist eine Erweiterung der WebGL API. Mit ihr dürfen Texturen, deren Pixel als 32-Bit-Gleitkommazahlen gespeichert sind (gl.FLOAT in WebGL 1 bzw. RGBA32F, RG32F, R32F usw. in WebGL 2), mit gl.LINEAR oder den Mipmap-Varianten gl.LINEAR_MIPMAP_NEAREST, gl.NEAREST_MIPMAP_LINEAR und gl.LINEAR_MIPMAP_LINEAR gefiltert werden. Ohne die Erweiterung ist bei solchen Texturen nur gl.NEAREST zulässig.

Die Erweiterung hat keine eigenen Methoden oder Konstanten. Es reicht, sie mit gl.getExtension("OES_texture_float_linear") einzuschalten. Danach gelten die neuen Filtermodi. Gibt der Aufruf null zurück, unterstützt das Gerät keine lineare Filterung von Float-Texturen.

Wichtig ist sie für HDR-Rendering, Umgebungs- und Lichtkarten (Image Based Lighting), Höhenfelder, GPU-Simulationen (Flüssigkeiten, Partikel) und Volumen-Rendering. Überall dort sollen Werte zwischen Texeln weich interpoliert werden, ohne dass Genauigkeit verloren geht.

  • WebGL 1: Voraussetzung ist zusätzlich OES_texture_float. Erst diese Erweiterung erlaubt Float-Texturen überhaupt.
  • WebGL 2: Float-Texturen gehören hier zum Standard. Lineare Filterung von 32-Bit-Formaten braucht aber weiterhin diese Erweiterung. 16-Bit-Formate (RGBA16F) lassen sich in WebGL 2 ohnehin linear filtern.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Der Name, den man an gl.getExtension() übergibt: genau "OES_texture_float_linear". Das Interface selbst hat keine Parameter, Methoden oder Konstanten.

Rückgabewert

Typ
OES_texture_float_linear | null
Beschreibung
gl.getExtension("OES_texture_float_linear") gibt ein (leeres) Erweiterungsobjekt zurück, wenn die Erweiterung unterstützt wird, sonst null. Schon der erfolgreiche Aufruf schaltet die lineare Filterung ein.

Beispiele

WebGL 1: Float-Textur mit linearer Filterung

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

// Beide Erweiterungen nötig: Float-Texturen + lineare Filterung
const floatExt = gl.getExtension("OES_texture_float");
const linearExt = gl.getExtension("OES_texture_float_linear");

if (!floatExt) {
  throw new Error("Float-Texturen werden nicht unterstützt");
}

const size = 4;
const data = new Float32Array(size * size * 4).map(() => Math.random() * 10);

const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.FLOAT, data);

const filter = linearExt ? gl.LINEAR : gl.NEAREST;
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, filter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, filter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

console.log("Filter:", filter === gl.LINEAR ? "LINEAR" : "NEAREST");
Filter: LINEAR

WebGL 2: HDR-Textur (RGBA32F) mit Rückfall auf RGBA16F

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

const canFilterFloat32 = gl.getExtension("OES_texture_float_linear") !== null;

const width = 256, height = 128;
const pixels = new Float32Array(width * height * 4).fill(2.5); // HDR-Werte > 1

const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);

// Ohne Erweiterung auf RGBA16F ausweichen, das in WebGL 2 immer filterbar ist
const internalFormat = canFilterFloat32 ? gl.RGBA32F : gl.RGBA16F;
gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, width, height, 0, gl.RGBA, gl.FLOAT, pixels);

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

console.log(canFilterFloat32 ? "RGBA32F + LINEAR" : "RGBA16F + LINEAR");
RGBA32F + LINEAR

Wiederverwendbare Prüfung der Float-Fähigkeiten

const getFloatCaps = (gl) => {
  const isWebGL2 = typeof WebGL2RenderingContext !== "undefined" &&
    gl instanceof WebGL2RenderingContext;
  const supported = gl.getSupportedExtensions() ?? [];
  return {
    webgl2: isWebGL2,
    floatTextures: isWebGL2 || supported.includes("OES_texture_float"),
    floatLinear: supported.includes("OES_texture_float_linear"),
    renderToFloat: supported.includes(isWebGL2 ? "EXT_color_buffer_float" : "WEBGL_color_buffer_float")
  };
};

const gl = document.createElement("canvas").getContext("webgl2")
  ?? document.createElement("canvas").getContext("webgl");
console.log(getFloatCaps(gl));
{ webgl2: true, floatTextures: true, floatLinear: true, renderToFloat: true }

// Wichtig · Fallstricke

  • Stiller Fehler: Wird eine 32-Bit-Float-Textur ohne aktivierte Erweiterung mit LINEAR gefiltert, meldet WebGL keinen Fehler. Die Textur gilt dann als unvollständig, und der Shader liest (0, 0, 0, 1), also Schwarz. Deshalb immer den Rückgabewert von getExtension() prüfen.
  • Nicht nur prüfen, sondern aktivieren: Dass der Name in getSupportedExtensions() steht, reicht nicht. Erst getExtension() schaltet die Erweiterung ein.
  • Nur Filterung: Die Erweiterung erlaubt kein Rendern in Float-Texturen. Dafür braucht man WEBGL_color_buffer_float (WebGL 1) bzw. EXT_color_buffer_float (WebGL 2).
  • Half-Float: Für HALF_FLOAT_OES in WebGL 1 ist stattdessen OES_texture_half_float_linear zuständig.
  • Kompatibilität: Desktop-Browser unterstützen die Erweiterung fast immer. Auf vielen Mobil-GPUs (vor allem älteren Android- und iOS-Geräten) fehlt sie. Planen Sie einen Rückfall ein, etwa RGBA16F oder NEAREST mit Interpolation im Shader.
  • Leistung: Lineare Filterung von 32-Bit-Texturen kann auf manchen GPUs deutlich langsamer sein als bei 8- oder 16-Bit-Formaten.