Signatur
Beschreibung
Die Erweiterung WEBGL_compressed_texture_pvrtc gehört zur WebGL-API und stellt die Texturkompression PVRTC (PowerVR Texture Compression) von Imagination Technologies zur Verfügung. PVRTC-Texturen bleiben auch im Grafikspeicher komprimiert. Das spart VRAM und Speicherbandbreite und verkürzt die Ladezeiten. Das hilft besonders auf Mobilgeräten mit PowerVR-GPU, allen voran bei älteren iPhones und iPads.
Ein Objekt der Erweiterung erhältst du über gl.getExtension("WEBGL_compressed_texture_pvrtc"). Es hat keine Methoden, sondern nur vier Konstanten, die du als internalformat an gl.compressedTexImage2D() übergibst:
COMPRESSED_RGB_PVRTC_4BPPV1_IMG(0x8C00): RGB, 4 Bit pro PixelCOMPRESSED_RGB_PVRTC_2BPPV1_IMG(0x8C01): RGB, 2 Bit pro PixelCOMPRESSED_RGBA_PVRTC_4BPPV1_IMG(0x8C02): RGBA, 4 Bit pro PixelCOMPRESSED_RGBA_PVRTC_2BPPV1_IMG(0x8C03): RGBA, 2 Bit pro Pixel
Die Texturdaten musst du vorher mit einem Werkzeug wie PVRTexTool erzeugen, etwa als .pvr- oder .ktx-Datei. Zur Laufzeit komprimiert WebGL nicht. Da PVRTC nur auf bestimmter Hardware läuft, solltest du immer eine Ausweichlösung einplanen, z. B. S3TC/DXT auf dem Desktop, ETC auf Android, ASTC oder unkomprimierte Texturen. Für neue Projekte ist ein universelles Format wie Basis Universal/KTX2 ratsam, das zur Laufzeit in das passende Zielformat umgewandelt wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $name Pflicht | string | Argument für gl.getExtension(): exakt "WEBGL_compressed_texture_pvrtc". Ältere WebKit-Versionen kennen zusätzlich "WEBKIT_WEBGL_compressed_texture_pvrtc". |
Rückgabewert
null, wenn die Hardware bzw. der Browser PVRTC nicht unterstützt.Beispiele
Unterstützung prüfen und Konstanten auslesen
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2') ?? canvas.getContext('webgl');
const pvrtc =
gl.getExtension('WEBGL_compressed_texture_pvrtc') ??
gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc');
if (pvrtc) {
console.log('PVRTC verfügbar');
console.log(pvrtc.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG.toString(16));
} else {
console.log('PVRTC nicht verfügbar – Fallback nutzen');
}
Datengröße eines PVRTC-Mip-Levels berechnen
// PVRTC hat Mindestblockgrößen: 4bpp → 8×8, 2bpp → 16×8
const pvrtcByteLength = (width, height, bpp) => {
const w = Math.max(width, bpp === 4 ? 8 : 16);
const h = Math.max(height, 8);
return (w * h * bpp) / 8;
};
console.log(pvrtcByteLength(512, 512, 4));
console.log(pvrtcByteLength(4, 4, 2));
Komprimierte Textur mit Mipmaps hochladen
const loadPvrtcTexture = async (gl, url, size) => {
const ext = gl.getExtension('WEBGL_compressed_texture_pvrtc');
if (!ext) throw new Error('PVRTC wird nicht unterstützt');
// Annahme: Datei enthält rohe PVRTC-Daten aller Mip-Level hintereinander
const buffer = await (await fetch(url)).arrayBuffer();
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
let offset = 0;
let level = 0;
for (let s = size; s >= 1; s >>= 1, level++) {
const byteLength = (Math.max(s, 8) * Math.max(s, 8) * 4) / 8;
const data = new Uint8Array(buffer, offset, byteLength);
gl.compressedTexImage2D(
gl.TEXTURE_2D, level,
ext.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG,
s, s, 0, data
);
offset += byteLength;
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
return tex;
};
// Aufruf: const tex = await loadPvrtcTexture(gl, 'stein.pvrtc', 256);
Formatauswahl mit Fallback-Kette
const pickTextureFormat = (gl) => {
if (gl.getExtension('WEBGL_compressed_texture_astc')) return 'astc';
if (gl.getExtension('WEBGL_compressed_texture_s3tc')) return 's3tc';
if (gl.getExtension('WEBGL_compressed_texture_etc')) return 'etc';
if (gl.getExtension('WEBGL_compressed_texture_pvrtc')) return 'pvrtc';
return 'png';
};
const gl = document.createElement('canvas').getContext('webgl');
console.log(`Lade Texturen im Format: ${pickTextureFormat(gl)}`);