Start · Sprachen · JavaScript · Referenz · WEBGL_compressed_texture_etc1 extension

WEBGL_compressed_texture_etc1 extension

Schnittstelle

WebGL-Erweiterung, die das komprimierte Texturformat ETC1 (<code>COMPRESSED_RGB_ETC1_WEBGL</code>) für <code>compressedTexImage2D()</code> bereitstellt.

seit JavaScript WebGL 1 / WebGL 2 — vor allem Android/mobile GPUs; Kategorie: webapi

Signatur

interface WEBGL_compressed_texture_etc1

Beschreibung

Die Erweiterung WEBGL_compressed_texture_etc1 gehört zur WebGL API. Mit ihr kann man Texturen im Format ETC1 (Ericsson Texture Compression) direkt an die GPU übergeben. ETC1 speichert RGB-Daten mit 4 Bit pro Pixel in 4×4-Blöcken und ist auf fast allen OpenGL-ES-2.0-Geräten vorhanden, vor allem auf Android. Die GPU liest die Daten im komprimierten Zustand. Das spart Grafikspeicher und Bandbreite und verkürzt die Ladezeiten.

Das Erweiterungsobjekt bekommt man über gl.getExtension('WEBGL_compressed_texture_etc1'). Es hat keine Methoden, sondern nur eine Konstante:

  • ext.COMPRESSED_RGB_ETC1_WEBGL (0x8D64): RGB, ohne Alphakanal.

Die Konstante wird als internalformat-Argument an gl.compressedTexImage2D() übergeben. compressedTexSubImage2D() ist für ETC1 nicht erlaubt. Die Texturdaten müssen vorab mit Werkzeugen wie etcpak, PVRTexTool oder im KTX-Container erzeugt werden.

ETC1 bietet sich an, wenn man opake Texturen wie Gelände, Fotos oder Hintergründe für Mobilgeräte optimieren will. Für Texturen mit Transparenz und für WebGL 2 ist WEBGL_compressed_texture_etc (ETC2/EAC) die bessere Wahl. Plattformübergreifend lohnt sich ein Fallback auf S3TC, ASTC oder unkomprimierte Texturen.

Parameter

Name Typ Default Beschreibung
$name Pflicht string Erweiterungsname für gl.getExtension(): genau 'WEBGL_compressed_texture_etc1'.

Rückgabewert

Typ
WEBGL_compressed_texture_etc1 | null
Beschreibung
gl.getExtension() gibt das Erweiterungsobjekt mit der Konstante COMPRESSED_RGB_ETC1_WEBGL zurück. Wenn Browser oder GPU ETC1 nicht unterstützen, ist der Rückgabewert null.

Beispiele

Erweiterung abfragen und Unterstützung prüfen

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

const ext = gl.getExtension('WEBGL_compressed_texture_etc1');
if (ext) {
  console.log('ETC1 unterstützt, Format:', ext.COMPRESSED_RGB_ETC1_WEBGL.toString(16));
} else {
  console.log('ETC1 nicht verfügbar');
}

// Alle komprimierten Formate des Kontexts auflisten
console.log(gl.getParameter(gl.COMPRESSED_TEXTURE_FORMATS));
ETC1 unterstützt, Format: 8d64 Uint32Array [36196]

ETC1-Textur aus Rohdaten hochladen

const loadEtc1Texture = async (gl, url, width, height) => {
  const ext = gl.getExtension('WEBGL_compressed_texture_etc1');
  if (!ext) throw new Error('ETC1 wird nicht unterstützt');

  // Rohe ETC1-Blockdaten ohne Header: 8 Byte pro 4×4-Block
  const buffer = await (await fetch(url)).arrayBuffer();
  const expected = Math.ceil(width / 4) * Math.ceil(height / 4) * 8;
  const data = new Uint8Array(buffer, 0, expected);

  const texture = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, texture);
  gl.compressedTexImage2D(
    gl.TEXTURE_2D, 0, ext.COMPRESSED_RGB_ETC1_WEBGL,
    width, height, 0, data
  );
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
  return texture;
};

const gl = document.querySelector('canvas').getContext('webgl');
const tex = await loadEtc1Texture(gl, 'textures/ground.etc1', 512, 512);
console.log(gl.getError() === gl.NO_ERROR ? 'Textur geladen' : 'Fehler');
Textur geladen

Formatauswahl mit Fallback

const pickTextureFormat = (gl) => {
  const astc = gl.getExtension('WEBGL_compressed_texture_astc');
  if (astc) return { type: 'astc', ext: astc };
  const s3tc = gl.getExtension('WEBGL_compressed_texture_s3tc');
  if (s3tc) return { type: 's3tc', ext: s3tc };
  const etc1 = gl.getExtension('WEBGL_compressed_texture_etc1');
  if (etc1) return { type: 'etc1', ext: etc1 };
  return { type: 'png', ext: null }; // unkomprimiert
};

const gl = document.createElement('canvas').getContext('webgl');
console.log('Lade Texturen im Format:', pickTextureFormat(gl).type);
Lade Texturen im Format: etc1

// Wichtig · Fallstricke

  • Kein Alphakanal: ETC1 speichert nur RGB. Für Transparenz braucht man eine zweite Textur als Alpha-Maske oder ETC2 (WEBGL_compressed_texture_etc).
  • Kein compressedTexSubImage2D(): Ein Aufruf mit ETC1 erzeugt INVALID_OPERATION. Teilbereiche lassen sich nicht aktualisieren.
  • Datengröße: Die Länge des ArrayBufferView muss genau ceil(w/4) * ceil(h/4) * 8 Byte betragen. Sonst entsteht INVALID_VALUE. Header von KTX- oder PKM-Dateien muss man vorher abschneiden.
  • Mipmaps: gl.generateMipmap() funktioniert bei komprimierten Texturen nicht. Jede Mip-Stufe muss einzeln hochgeladen werden. In WebGL 1 ist Mipmapping außerdem nur bei Seitenlängen mit Zweierpotenz möglich.
  • Kompatibilität: Die Unterstützung ist vor allem auf Android/mobilen GPUs verbreitet. Auf Desktop-GPUs und in Safari/iOS fehlt die Erweiterung oft. Deshalb immer auf null prüfen und einen Fallback vorsehen. Eine Alternative ist Basis Universal/KTX2, das zur Laufzeit in das passende Format umwandelt.
  • Rufen Sie getExtension() auf, bevor Sie die Konstante verwenden. Erst dieser Aufruf aktiviert das Format im Kontext.