Signatur
Beschreibung
texSubImage3D() schreibt Pixeldaten in einen Teilbereich einer schon angelegten Textur vom Typ gl.TEXTURE_3D oder gl.TEXTURE_2D_ARRAY. Der Bereich wird über einen Versatz (xoffset, yoffset, zoffset) und eine Größe (width, height, depth) festgelegt. Bei Textur-Arrays steht die z-Achse für den Index der Ebene (Layer).
Anders als texImage3D() belegt die Methode keinen neuen Speicher. Sie aktualisiert nur vorhandene Texel. Deshalb eignet sie sich für häufige Updates, etwa für Volumendaten beim Streaming, Sprite-Atlanten in Textur-Arrays oder das nachträgliche Befüllen einzelner Ebenen. Der Speicher wird vorher mit texStorage3D() (unveränderlich, empfohlen) oder mit texImage3D() angelegt.
Die Methode hat mehrere Überladungen. Die Quelle kann ein ArrayBufferView sein (optional mit srcOffset), ein Byte-Versatz in einen gebundenen PIXEL_UNPACK_BUFFER oder eine DOM-Bildquelle wie ImageBitmap, ImageData, HTMLImageElement, HTMLCanvasElement, HTMLVideoElement oder OffscreenCanvas. format und type müssen zum internen Format der Textur passen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | GLenum | Ziel der Textur: gl.TEXTURE_3D oder gl.TEXTURE_2D_ARRAY. |
|
| $level Pflicht | GLint | Mipmap-Stufe. 0 ist das Basisbild. |
|
| $xoffset Pflicht | GLint | Versatz in x-Richtung (Texel) innerhalb der Textur. | |
| $yoffset Pflicht | GLint | Versatz in y-Richtung (Texel). | |
| $zoffset Pflicht | GLint | Versatz in z-Richtung. Bei TEXTURE_2D_ARRAY ist das der Index der ersten Ebene. |
|
| $width Pflicht | GLsizei | Breite des Teilbereichs in Texeln. | |
| $height Pflicht | GLsizei | Höhe des Teilbereichs in Texeln. | |
| $depth Pflicht | GLsizei | Tiefe des Teilbereichs bzw. Anzahl der Ebenen. | |
| $format Pflicht | GLenum | Format der Quelldaten, z. B. gl.RGBA, gl.RED, gl.RG, gl.RGBA_INTEGER. |
|
| $type Pflicht | GLenum | Datentyp der Quelldaten, z. B. gl.UNSIGNED_BYTE, gl.FLOAT, gl.HALF_FLOAT. |
|
| $srcData Pflicht | ArrayBufferView | null | GLintptr | ImageBitmap | ImageData | HTMLImageElement | HTMLCanvasElement | HTMLVideoElement | OffscreenCanvas | VideoFrame | Quelle der Pixel. Ein typisiertes Array, das zu type passt (z. B. Uint8Array für UNSIGNED_BYTE), ein Byte-Versatz in den gebundenen PIXEL_UNPACK_BUFFER oder eine Bildquelle. |
|
| $srcOffset | GLuint | 0 | Nur bei ArrayBufferView: Startindex in Elementen (nicht in Bytes), ab dem gelesen wird. |
Rückgabewert
undefined). Fehler werden über gl.getError() gemeldet.Beispiele
3D-Textur anlegen und einen Teilquader aktualisieren
const canvas = document.createElement('canvas');
const gl = canvas.getContext('webgl2');
const size = 32;
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex);
// Unveränderlichen Speicher anlegen: 32×32×32 Texel, RGBA8
gl.texStorage3D(gl.TEXTURE_3D, 1, gl.RGBA8, size, size, size);
// 8×8×8-Block mit Rot füllen, beginnend bei (4, 4, 4)
const w = 8, h = 8, d = 8;
const data = new Uint8Array(w * h * d * 4);
for (let i = 0; i < data.length; i += 4) {
data[i] = 255; // R
data[i + 3] = 255; // A
}
gl.texSubImage3D(gl.TEXTURE_3D, 0, 4, 4, 4, w, h, d, gl.RGBA, gl.UNSIGNED_BYTE, data);
console.log(gl.getError() === gl.NO_ERROR);
Einzelne Ebene eines Textur-Arrays mit einem Bild befüllen
const gl = document.querySelector('canvas').getContext('webgl2');
const layers = 4, size = 256;
const texArray = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D_ARRAY, texArray);
gl.texStorage3D(gl.TEXTURE_2D_ARRAY, 1, gl.RGBA8, size, size, layers);
gl.texParameteri(gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
const loadLayer = async (url, layer) => {
const blob = await (await fetch(url)).blob();
const bitmap = await createImageBitmap(blob, { resizeWidth: size, resizeHeight: size });
gl.bindTexture(gl.TEXTURE_2D_ARRAY, texArray);
// depth = 1 -> genau eine Ebene, zoffset = Ebenenindex
gl.texSubImage3D(gl.TEXTURE_2D_ARRAY, 0, 0, 0, layer, size, size, 1,
gl.RGBA, gl.UNSIGNED_BYTE, bitmap);
bitmap.close();
};
await loadLayer('/img/gras.png', 0);
await loadLayer('/img/stein.png', 1);
console.log('Ebenen geladen');
Float-Volumendaten mit srcOffset hochladen
const gl = document.createElement('canvas').getContext('webgl2');
const tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_3D, tex);
gl.texStorage3D(gl.TEXTURE_3D, 1, gl.R32F, 16, 16, 16);
// Gesamtes Volumen im Speicher, nur die obere Hälfte (z = 8..15) hochladen
const volume = new Float32Array(16 * 16 * 16).map(() => Math.random());
const sliceSize = 16 * 16;
gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
gl.texSubImage3D(gl.TEXTURE_3D, 0, 0, 0, 8, 16, 16, 8,
gl.RED, gl.FLOAT, volume, 8 * sliceSize); // srcOffset in Elementen
console.log(gl.getError());