Signatur
Beschreibung
createTexture() legt auf der GPU ein neues Textur-Objekt an und gibt einen Verweis darauf als WebGLTexture zurück. Die Textur ist zunächst leer. Sie hat weder eine Größe noch ein Format oder Bilddaten. Diese Eigenschaften bekommt sie erst, wenn sie mit bindTexture() an ein Ziel wie gl.TEXTURE_2D oder gl.TEXTURE_CUBE_MAP gebunden wird und dann Daten über texImage2D() oder texSubImage2D() erhält.
Texturen braucht man für fast jede sichtbare WebGL-Anwendung: Bilder auf Geometrie legen, Sprites, Schriftatlanten, Normal-Maps, Lookup-Tabellen oder als Farbziel für einen Framebuffer (Render-to-Texture). Der übliche Ablauf ist:
createTexture()– Objekt anlegenbindTexture(target, texture)– als aktive Textur setzentexParameteri()– Filterung und Wrap-Modus festlegentexImage2D()– Pixeldaten hochladen- optional
generateMipmap()
Die Methode gibt es genauso auf WebGL2RenderingContext. Dort lassen sich die Texturen zusätzlich mit gl.TEXTURE_3D und gl.TEXTURE_2D_ARRAY verwenden. Wird die Textur nicht mehr gebraucht, sollte man sie mit deleteTexture() ausdrücklich freigeben. Auf die Speicherbereinigung von JavaScript kann man sich beim GPU-Speicher nicht verlassen.
Rückgabewert
WebGLTexture-Objekt. Ist der Kontext verloren gegangen (isContextLost() liefert true), wird null zurückgegeben.Beispiele
Einfarbige Platzhalter-Textur anlegen
const canvas = document.querySelector('canvas');
const gl = canvas.getContext('webgl');
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
// 1×1-Pixel in Blau als Platzhalter
const pixel = new Uint8Array([0, 0, 255, 255]);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
console.log(gl.isTexture(texture));
Bild asynchron laden und als Textur verwenden
const loadTexture = (gl, url) => new Promise((resolve, reject) => {
const texture = gl.createTexture();
const image = new Image();
image.crossOrigin = 'anonymous';
image.onload = () => {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
// Sicher auch für Bildgrößen, die keine Zweierpotenz sind (WebGL 1)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
resolve(texture);
};
image.onerror = () => {
gl.deleteTexture(texture);
reject(new Error(`Bild konnte nicht geladen werden: ${url}`));
};
image.src = url;
});
const gl = document.querySelector('canvas').getContext('webgl');
const tex = await loadTexture(gl, '/img/stein.png');
console.log(tex instanceof WebGLTexture);
Textur als Render-Ziel (Framebuffer) nutzen und wieder freigeben
const gl = document.querySelector('canvas').getContext('webgl');
const width = 512, height = 512;
const target = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, target);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
const fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, target, 0);
const ok = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;
console.log('Framebuffer bereit:', ok);
// Aufräumen, wenn nicht mehr benötigt
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.deleteFramebuffer(fbo);
gl.deleteTexture(target);
// Wichtig · Fallstricke
- Ohne Parameter bleibt die Textur „unvollständig“: Der Standardwert von
TEXTURE_MIN_FILTERistNEAREST_MIPMAP_LINEAR. OhnegenerateMipmap()oder einen anderen Min-Filter wird die Textur beim Sampeln schwarz dargestellt. - Zweierpotenzen in WebGL 1: Bei Texturen, deren Größe keine Zweierpotenz ist (NPOT), sind nur
CLAMP_TO_EDGEund Filter ohne Mipmaps erlaubt. WebGL 2 hat diese Einschränkung nicht. - CORS: Bilder von fremden Domains dürfen nur hochgeladen werden, wenn
crossOrigingesetzt ist und der Server passende CORS-Header sendet. Sonst wirfttexImage2D()einenSecurityError. - Kontextverlust: Nach dem Ereignis
webglcontextlostsind alle Texturen ungültig. Nachwebglcontextrestoredmüssen sie neu erzeugt und neu befüllt werden. - Speicher: GPU-Speicher wird nicht zuverlässig von der Speicherbereinigung freigegeben. Nicht mehr benötigte Texturen sollte man mit
deleteTexture()ausdrücklich löschen. - Ein
WebGLTexturegehört immer zu genau dem Kontext, der es erzeugt hat. Mit einem anderen Kontext lässt es sich nicht verwenden. - Kompatibilität: Wird in allen modernen Browsern unterstützt (WebGL 1 und WebGL 2), auch in
OffscreenCanvasinnerhalb von Workern.