Start · Sprachen · JavaScript · Referenz · WEBGL_compressed_texture_pvrtc extension

WEBGL_compressed_texture_pvrtc extension

Schnittstelle

WebGL-Erweiterung, die vier komprimierte PVRTC-Texturformate (RGB/RGBA, 2 bzw. 4 Bit pro Pixel) für <code>compressedTexImage2D()</code> bereitstellt.

seit JavaScript WebGL 1 und WebGL 2; nur auf Geräten mit PowerVR-G Kategorie: webapi

Signatur

interface WEBGL_compressed_texture_pvrtc

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 Pixel
  • COMPRESSED_RGB_PVRTC_2BPPV1_IMG (0x8C01): RGB, 2 Bit pro Pixel
  • COMPRESSED_RGBA_PVRTC_4BPPV1_IMG (0x8C02): RGBA, 4 Bit pro Pixel
  • COMPRESSED_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

Typ
WEBGL_compressed_texture_pvrtc | null
Beschreibung
Das Erweiterungsobjekt mit den vier PVRTC-Formatkonstanten oder 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');
}
PVRTC verfügbar 8c02 (auf Geräten ohne PowerVR-GPU: "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));
131072 32

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)}`);
Lade Texturen im Format: s3tc (je nach Gerät unterschiedlich)