Signatur
Beschreibung
Mit compressedTexImage2D() übergeben Sie der GPU bereits komprimierte Texturdaten, die direkt im komprimierten Zustand im Grafikspeicher bleiben. Das spart Videospeicher und Bandbreite deutlich (typisch Faktor 4–8 gegenüber RGBA8) und ist daher in Spielen, 3D-Viewern und Kartenanwendungen mit vielen oder großen Texturen der Standardweg.
Die Daten werden nicht zur Laufzeit komprimiert – Sie müssen sie vorab mit Werkzeugen wie texconv, PVRTexTool, basisu oder toktx (KTX/KTX2, DDS) erzeugen. Welche Formate verfügbar sind, hängt von der Hardware ab und wird über Erweiterungen freigeschaltet, etwa WEBGL_compressed_texture_s3tc (Desktop), WEBGL_compressed_texture_etc, WEBGL_compressed_texture_astc oder WEBGL_compressed_texture_pvrtc (ältere iOS-Geräte). Die Format-Konstanten stammen aus dem jeweiligen Erweiterungsobjekt.
Jede Mipmap-Stufe wird mit einem eigenen Aufruf und passendem level hochgeladen. Für Teilaktualisierungen einer bestehenden komprimierten Textur verwenden Sie compressedTexSubImage2D(). In WebGL 2 existiert zusätzlich eine Überladung, die Daten aus einem gebundenen PIXEL_UNPACK_BUFFER liest (imageSize, offset) sowie Varianten mit srcOffset/srcLengthOverride.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | GLenum | — | Bindungspunkt der Textur: gl.TEXTURE_2D oder eine Würfelseite wie gl.TEXTURE_CUBE_MAP_POSITIVE_X … gl.TEXTURE_CUBE_MAP_NEGATIVE_Z. |
| $level Pflicht | GLint | — | Mipmap-Stufe; 0 ist das Basisbild, jede weitere Stufe halbiert Breite und Höhe. |
| $internalformat Pflicht | GLenum | — | Komprimiertes Format aus einer Erweiterung, z. B. ext.COMPRESSED_RGBA_S3TC_DXT5_EXT, ext.COMPRESSED_RGB8_ETC2 oder ext.COMPRESSED_RGBA_ASTC_4x4_KHR. |
| $width Pflicht | GLsizei | — | Breite des Bildes in Texeln. Muss zum Blockformat passen (bei S3TC meist Vielfaches von 4 für Stufe 0). |
| $height Pflicht | GLsizei | — | Höhe des Bildes in Texeln. |
| $border Pflicht | GLint | 0 | Rahmenbreite – muss immer 0 sein. |
| $pixels Pflicht | ArrayBufferView | — | Komprimierte Blockdaten, z. B. ein Uint8Array. Die Länge muss exakt der vom Format geforderten Bytegröße entsprechen. |
Rückgabewert
undefined). Fehler werden über gl.getError() gemeldet.Beispiele
Verfügbares Kompressionsformat ermitteln
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
// Erweiterungen in Reihenfolge der Präferenz prüfen
const formats = {
astc: gl.getExtension('WEBGL_compressed_texture_astc'),
s3tc: gl.getExtension('WEBGL_compressed_texture_s3tc'),
etc: gl.getExtension('WEBGL_compressed_texture_etc'),
etc1: gl.getExtension('WEBGL_compressed_texture_etc1')
};
const available = Object.entries(formats)
.filter(([, ext]) => ext !== null)
.map(([name]) => name);
console.log('Unterstützt:', available);
console.log(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS));
DXT5-Textur mit Mipmaps hochladen
const gl = document.querySelector('canvas').getContext('webgl');
const s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc');
if (!s3tc) throw new Error('S3TC wird nicht unterstützt');
// DXT5: 16 Byte pro 4×4-Block
const dxt5Size = (w, h) => Math.ceil(w / 4) * Math.ceil(h / 4) * 16;
const uploadDxt5 = (buffer, width, height, mipCount) => {
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
let offset = 0;
let w = width;
let h = height;
for (let level = 0; level < mipCount; level++) {
const size = dxt5Size(w, h);
const data = new Uint8Array(buffer, offset, size);
gl.compressedTexImage2D(gl.TEXTURE_2D, level,
s3tc.COMPRESSED_RGBA_S3TC_DXT5_EXT, w, h, 0, data);
offset += size;
w = Math.max(1, w >> 1);
h = Math.max(1, h >> 1);
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,
mipCount > 1 ? gl.LINEAR_MIPMAP_LINEAR : gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
console.log('Fehlercode:', gl.getError());
return tex;
};
// Beispiel: 256×256 mit 9 Mip-Stufen (Daten hier nur Platzhalter)
let total = 0;
for (let s = 256; s >= 1; s >>= 1) total += dxt5Size(s, s);
const texture = uploadDxt5(new ArrayBuffer(total), 256, 256, 9);
Komprimierte Textur aus einer Datei laden (async)
const gl = document.querySelector('canvas').getContext('webgl');
const s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc');
const loadRawDxt1 = async (url, width, height) => {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const data = new Uint8Array(await response.arrayBuffer());
// DXT1: 8 Byte pro 4×4-Block
const expected = Math.ceil(width / 4) * Math.ceil(height / 4) * 8;
if (data.byteLength < expected) throw new Error('Datei zu klein');
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.compressedTexImage2D(gl.TEXTURE_2D, 0,
s3tc.COMPRESSED_RGB_S3TC_DXT1_EXT, width, height, 0,
data.subarray(0, expected));
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
return tex;
};
const tex = await loadRawDxt1('/textures/stein_512.dxt1', 512, 512);
console.log(gl.isTexture(tex));