Start · Sprachen · JavaScript · Referenz · WebGLRenderingContext.unpackColorSpace

WebGLRenderingContext.unpackColorSpace

Eigenschaft

Legt fest, in welchen Farbraum (<code>"srgb"</code> oder <code>"display-p3"</code>) Bildquellen beim Hochladen als Textur per <code>texImage2D()</code>/<code>texSubImage2D()</code> konvertiert werden.

seit JavaScript Chrome/Edge 104+, Safari 16.4+; Firefox: noch nich Kategorie: webapi

Signatur

WebGLRenderingContext.unpackColorSpace

Beschreibung

Die Eigenschaft unpackColorSpace eines WebGL-Kontexts (WebGLRenderingContext und WebGL2RenderingContext) bestimmt den Ziel-Farbraum für Texturdaten. Lädst du ein HTMLImageElement, ImageBitmap, HTMLVideoElement, HTMLCanvasElement, OffscreenCanvas oder ImageData mit texImage2D() oder texSubImage2D() hoch, konvertiert der Browser die Pixel vorher aus dem Quell-Farbraum in diesen Farbraum.

Gültige Werte sind "srgb" (Standard) und "display-p3". Mit "display-p3" bleibt der erweiterte Farbumfang von P3-Bildern erhalten (z. B. Fotos von aktuellen Smartphones), sonst werden sie auf sRGB beschnitten. Die Eigenschaft ist lesbar und schreibbar. Eine Änderung wirkt nur auf nachfolgende Uploads, bereits hochgeladene Texturen bleiben unverändert.

Setze die Eigenschaft in der Regel passend zu drawingBufferColorSpace. So liegen Texturen und Ausgabepuffer im selben Farbraum, und Shader rechnen konsistent. Ob die Konvertierung überhaupt stattfindet, hängt außerdem vom Pixelspeicher-Parameter UNPACK_COLORSPACE_CONVERSION_WEBGL ab. Steht er auf gl.NONE, findet keine Farbraum-Konvertierung statt.

Rückgabewert

Typ
"srgb" | "display-p3"
Beschreibung
Ein String mit dem aktuellen Ziel-Farbraum für Textur-Uploads. Der Standardwert ist "srgb". Beim Setzen sind nur diese beiden Werte erlaubt.

Beispiele

Aktuellen Wert auslesen und Unterstützung prüfen

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

if ('unpackColorSpace' in gl) {
  console.log('unpackColorSpace:', gl.unpackColorSpace);
} else {
  console.log('unpackColorSpace wird nicht unterstützt');
}
unpackColorSpace: srgb

P3-Foto ohne Farbverlust als Textur laden

const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl2');

// Nur auf P3 umschalten, wenn der Bildschirm den Farbraum darstellen kann
const wideGamut = matchMedia('(color-gamut: p3)').matches;
if (wideGamut && 'unpackColorSpace' in gl) {
  gl.drawingBufferColorSpace = 'display-p3';
  gl.unpackColorSpace = 'display-p3';
}

const loadTexture = async (url) => {
  const img = new Image();
  img.src = url;
  await img.decode();

  const tex = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tex);
  // Wird jetzt in den Farbraum aus unpackColorSpace konvertiert
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  return tex;
};

const texture = await loadTexture('/bilder/sonnenuntergang-p3.jpg');
console.log(gl.unpackColorSpace);
display-p3

Farbraum zwischen Uploads umschalten

const gl = document.createElement('canvas').getContext('webgl2');
const bitmap = await createImageBitmap(await (await fetch('/icon.png')).blob());

const texSrgb = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texSrgb);
gl.unpackColorSpace = 'srgb';
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);

const texP3 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texP3);
gl.unpackColorSpace = 'display-p3'; // betrifft nur diesen und folgende Uploads
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, bitmap);

gl.unpackColorSpace = 'rec2020'; // ungültig: Wert wird ignoriert
console.log(gl.unpackColorSpace);
display-p3

// Wichtig · Fallstricke

  • Browserunterstützung: Chromium-Browser ab Version 104 und Safari ab 16.4 unterstützen die Eigenschaft. Firefox unterstützt sie derzeit nicht. Prüfe sie deshalb mit 'unpackColorSpace' in gl. Ohne Unterstützung werden Texturen wie bisher als sRGB behandelt.
  • Nur für Bildquellen: Rohdaten aus ArrayBufferViews (z. B. Uint8Array) werden nie konvertiert. Die Eigenschaft wirkt nur auf DOM- und Bild-Objekte.
  • Konvertierung ausschalten: Mit gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE) findet keine Konvertierung statt. Das ist wichtig für Daten-Texturen wie Normal Maps, Höhenkarten oder Lookup-Tabellen, deren Werte nicht verändert werden dürfen.
  • Ungültige Werte: Andere Strings als "srgb" oder "display-p3" werden ignoriert, der bisherige Wert bleibt erhalten. Je nach Implementierung erscheint eine Warnung in der Konsole.
  • Kein Gamma-Ersatz: Die Eigenschaft ändert nur die Farbprimärfarben (Gamut). Lineares Rechnen im Shader musst du weiterhin selbst umsetzen oder dafür sRGB-Texturformate wie SRGB8_ALPHA8 verwenden.
  • Leistung: Die Konvertierung kostet beim Upload etwas Zeit. Das kann bei vielen Video-Frames pro Sekunde messbar sein.