Signatur
Beschreibung
Die Erweiterung OES_texture_float gehört zur WebGL-API. Sie erlaubt es, gl.FLOAT als Typ-Parameter in texImage2D() und texSubImage2D() anzugeben. Texturen speichern ihre Werte dann als 32-Bit-Gleitkommazahlen statt als 8-Bit-Ganzzahlen von 0 bis 255. Die Schnittstelle bringt weder eigene Methoden noch Konstanten mit. Ist die Erweiterung aktiviert, akzeptiert WebGL einfach den bereits vorhandenen Wert gl.FLOAT.
Gleitkomma-Texturen braucht man vor allem für GPGPU-Berechnungen (z. B. Partikelsimulationen, Physik, Bildfilter mit hoher Genauigkeit), für HDR-Rendering, Shadow Maps, Deferred Shading und für Daten wie Höhenkarten, deren Werte außerhalb von [0, 1] liegen.
Sie aktivieren die Erweiterung mit gl.getExtension('OES_texture_float'). Ist sie nicht verfügbar, erhalten Sie null. Wichtig: Die Erweiterung erlaubt nur das Hochladen und Abtasten mit gl.NEAREST. Für lineare Filterung brauchen Sie zusätzlich OES_texture_float_linear. Um in eine Float-Textur zu rendern (als Anhang eines Framebuffers), brauchen Sie WEBGL_color_buffer_float.
In WebGL 2 ist die Funktion Teil des Kerns. Dort nutzen Sie ein Sized Internal Format wie gl.RGBA32F zusammen mit gl.FLOAT. Die Erweiterung gibt es in WebGL-2-Kontexten nicht.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Argument für gl.getExtension(): exakt 'OES_texture_float'. |
Rückgabewert
gl.getExtension('OES_texture_float') gibt das Erweiterungsobjekt zurück, falls die Erweiterung unterstützt wird, sonst null. Das Objekt selbst hat keine Eigenschaften oder Methoden.Beispiele
Erweiterung aktivieren und Unterstützung prüfen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl');
const ext = gl.getExtension('OES_texture_float');
if (!ext) {
console.warn('Gleitkomma-Texturen werden nicht unterstützt.');
} else {
console.log('OES_texture_float aktiv:', ext);
}
Float-Textur mit Simulationsdaten erstellen
const gl = document.createElement('canvas').getContext('webgl');
if (!gl.getExtension('OES_texture_float')) {
throw new Error('Keine Float-Texturen verfügbar');
}
const size = 64;
// Positionen von 64×64 Partikeln (RGBA = x, y, z, w)
const data = new Float32Array(size * size * 4);
for (let i = 0; i < data.length; i += 4) {
data[i] = Math.random() * 100 - 50; // Werte außerhalb von [0,1] möglich
data[i + 1] = Math.random() * 100 - 50;
data[i + 2] = 0;
data[i + 3] = 1;
}
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
// Ohne OES_texture_float_linear nur NEAREST verwenden!
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
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);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, size, size, 0, gl.RGBA, gl.FLOAT, data);
console.log('Fehler:', gl.getError() === gl.NO_ERROR ? 'keiner' : gl.getError());
Prüfen, ob in Float-Texturen gerendert werden kann
const gl = document.createElement('canvas').getContext('webgl');
gl.getExtension('OES_texture_float');
gl.getExtension('WEBGL_color_buffer_float');
const canRenderToFloat = () => {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 4, 4, 0, gl.RGBA, gl.FLOAT, null);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
const ok = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fb);
gl.deleteTexture(tex);
return ok;
};
console.log('Render-to-Float möglich:', canRenderToFloat());
WebGL 2: gleiche Funktion ohne Erweiterung
const gl2 = document.createElement('canvas').getContext('webgl2');
const tex = gl2.createTexture();
gl2.bindTexture(gl2.TEXTURE_2D, tex);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MIN_FILTER, gl2.NEAREST);
gl2.texParameteri(gl2.TEXTURE_2D, gl2.TEXTURE_MAG_FILTER, gl2.NEAREST);
// Sized Internal Format RGBA32F statt RGBA
gl2.texImage2D(gl2.TEXTURE_2D, 0, gl2.RGBA32F, 2, 2, 0, gl2.RGBA, gl2.FLOAT,
new Float32Array(16).fill(1.5));
console.log(gl2.getExtension('OES_texture_float'));
// Wichtig · Fallstricke
- Filterung: Ohne
OES_texture_float_linearist eine Float-Textur mitgl.LINEARoder Mipmap-Filtern „unvollständig“. Im Shader wird sie dann als Schwarz (0, 0, 0, 1) abgetastet. Eine Fehlermeldung gibt es dabei nicht. - Rendern in Float-Texturen: Das garantiert die Erweiterung nicht. Aktivieren Sie
WEBGL_color_buffer_floatund prüfen Sie immer mitcheckFramebufferStatus(). Manche älteren Implementierungen haben das stillschweigend erlaubt. Darauf sollten Sie sich nicht verlassen. - Mobilgeräte: Viele Mobil-GPUs unterstützen zwar 16-Bit-Floats (
OES_texture_half_float), aber keine 32-Bit-Floats oder deren Filterung. Planen Sie eine Ausweichlösung ein. - Datenquelle: Mit
gl.FLOATmuss das Pixel-Array einFloat32Arraysein. EinUint8Arrayführt zuINVALID_OPERATION. - WebGL 2: Dort gibt
getExtension('OES_texture_float')nullzurück. Verwenden Sie Sized Formats wiegl.RGBA32F,gl.R32Fund für FramebufferEXT_color_buffer_float. - Speicher: Eine RGBA32F-Textur belegt 16 Byte pro Pixel, viermal so viel wie RGBA8. Eine 4096×4096-Textur braucht also etwa 256 MB.
- Fingerprinting: Welche Erweiterungen verfügbar sind, kann zur Identifizierung von Geräten beitragen. Einige Browser schränken die Liste deshalb im Datenschutzmodus ein.