Start · Sprachen · JavaScript · Referenz · GPUDevice.createTexture()

GPUDevice.createTexture()

Methode

Erstellt eine <code>GPUTexture</code>, die 1D-, 2D- oder 3D-Daten wie Bilder, Tiefenpuffer oder Render-Ziele für GPU-Operationen speichert.

seit JavaScript WebGPU – Chrome/Edge 113+, Safari 26+, Firefox 141 Kategorie: webapi

Signatur

GPUDevice.prototype.createTexture(descriptor)

Beschreibung

createTexture() legt auf einem GPUDevice eine neue Textur an, also einen strukturierten Speicherbereich auf der GPU. In diese Textur lassen sich Bilddaten hochladen (GPUQueue.writeTexture(), copyExternalImageToTexture()), sie kann als Render-Ziel (Farb- oder Tiefenanhang) dienen und in Shadern gesampelt oder als Storage-Textur beschrieben werden.

Der Deskriptor legt Größe, Format, Dimension, Mip-Level-Anzahl, Multisampling und – ganz wichtig – die erlaubten Verwendungszwecke (usage) fest. Diese Eigenschaften sind unveränderlich: Wer später eine andere Größe (z. B. nach einem Fenster-Resize) oder ein anderes Format braucht, muss eine neue Textur erstellen und die alte mit destroy() freigeben.

Die Methode arbeitet synchron und gibt sofort ein GPUTexture-Objekt zurück. Ungültige Deskriptoren werfen normalerweise keine Ausnahme, sondern erzeugen einen Validierungsfehler und eine ungültige Textur. Solche Fehler fängt man mit device.pushErrorScope("validation") / popErrorScope() oder über das Ereignis uncapturederror ab.

Parameter

Name Typ Default Beschreibung
$descriptor Pflicht GPUTextureDescriptor Konfigurationsobjekt mit den unten aufgeführten Eigenschaften.
$descriptor.size Pflicht GPUExtent3D (Array | {width, height?, depthOrArrayLayers?}) Größe in Texeln, z. B. [512, 512] oder { width: 512, height: 512, depthOrArrayLayers: 6 }. Nicht angegebene Werte für height/depthOrArrayLayers sind 1.
$descriptor.format Pflicht GPUTextureFormat (string) Texelformat, z. B. "rgba8unorm", "bgra8unorm", "depth24plus", "rgba16float".
$descriptor.usage Pflicht number (GPUTextureUsageFlags) Bitmaske aus GPUTextureUsage.COPY_SRC, COPY_DST, TEXTURE_BINDING, STORAGE_BINDING, RENDER_ATTACHMENT, mit | verknüpft.
$descriptor.dimension "1d" | "2d" | "3d" "2d" Dimension der Textur.
$descriptor.mipLevelCount number 1 Anzahl der Mip-Level. Maximal floor(log2(max(width, height))) + 1.
$descriptor.sampleCount number 1 Anzahl der Samples pro Texel; 1 oder 4 (Multisampling). Bei 4 muss mipLevelCount 1 sein, und STORAGE_BINDING ist nicht erlaubt.
$descriptor.viewFormats Array<GPUTextureFormat> [] Weitere Formate, die für createView() erlaubt sind, z. B. ["rgba8unorm-srgb"] für eine rgba8unorm-Textur. Erlaubt sind nur Formate, die sich lediglich in sRGB/linear unterscheiden.
$descriptor.textureBindingViewDimension GPUTextureViewDimension Nur für Kompatibilitätsmodus: legt die View-Dimension (z. B. "cube") bei der Bindung fest.
$descriptor.label string "" Name zur Fehlersuche; erscheint in Fehlermeldungen und Debug-Werkzeugen.

Rückgabewert

Typ
GPUTexture
Beschreibung
Das neu erstellte Texturobjekt. Bei ungültigem Deskriptor ist es ein ungültiges Objekt, und es wird ein Validierungsfehler ausgelöst.

Beispiele

Bild laden und als Textur hochladen

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const response = await fetch('/img/logo.png');
const bitmap = await createImageBitmap(await response.blob());

const texture = device.createTexture({
  label: 'Logo-Textur',
  size: [bitmap.width, bitmap.height],
  format: 'rgba8unorm',
  usage: GPUTextureUsage.TEXTURE_BINDING |
         GPUTextureUsage.COPY_DST |
         GPUTextureUsage.RENDER_ATTACHMENT // für copyExternalImageToTexture nötig
});

device.queue.copyExternalImageToTexture(
  { source: bitmap },
  { texture },
  [bitmap.width, bitmap.height]
);

console.log(texture.width, texture.height, texture.format);
256 256 rgba8unorm

Tiefenpuffer für eine Render-Pass-Konfiguration

const canvas = document.querySelector('canvas');
const context = canvas.getContext('webgpu');

const depthTexture = device.createTexture({
  label: 'Tiefenpuffer',
  size: [canvas.width, canvas.height],
  format: 'depth24plus',
  usage: GPUTextureUsage.RENDER_ATTACHMENT
});

const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
  colorAttachments: [{
    view: context.getCurrentTexture().createView(),
    clearValue: { r: 0, g: 0, b: 0, a: 1 },
    loadOp: 'clear',
    storeOp: 'store'
  }],
  depthStencilAttachment: {
    view: depthTexture.createView(),
    depthClearValue: 1.0,
    depthLoadOp: 'clear',
    depthStoreOp: 'store'
  }
});
pass.end();
device.queue.submit([encoder.finish()]);

Pixeldaten schreiben und Validierungsfehler abfangen

device.pushErrorScope('validation');

const size = 4;
const tex = device.createTexture({
  size: [size, size],
  format: 'rgba8unorm',
  mipLevelCount: 3, // max. floor(log2(4)) + 1 = 3
  usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
});

// Schachbrettmuster für Mip-Level 0
const data = new Uint8Array(size * size * 4);
for (let i = 0; i < size * size; i++) {
  const v = ((i % size) + Math.floor(i / size)) % 2 ? 255 : 0;
  data.set([v, v, v, 255], i * 4);
}
device.queue.writeTexture(
  { texture: tex },
  data,
  { bytesPerRow: size * 4 },
  [size, size]
);

const error = await device.popErrorScope();
console.log(error ? `Fehler: ${error.message}` : 'Textur OK', tex.mipLevelCount);
Textur OK 3

// Wichtig · Fallstricke

  • Keine Ausnahme bei Fehlern: Falsche Formate, zu große Abmessungen (über device.limits.maxTextureDimension2D, oft 8192) oder zu viele Mip-Level erzeugen nur einen Validierungsfehler. Deshalb Error-Scopes verwenden oder label setzen, damit sich Fehler leichter finden lassen.
  • usage ist unveränderlich: Fehlt z. B. COPY_DST, schlägt writeTexture() fehl. copyExternalImageToTexture() braucht zusätzlich RENDER_ATTACHMENT.
  • Speicher freigeben: Texturen belegen GPU-Speicher. Nicht mehr benötigte Texturen, etwa nach einem Canvas-Resize, sollte man mit texture.destroy() sofort freigeben, statt auf die Speicherbereinigung zu warten.
  • Formate: Manche Formate brauchen Features, z. B. texture-compression-bc für BC-Formate oder float32-filterable, die bei requestDevice() angefordert werden müssen. Für Canvas-Ziele liefert navigator.gpu.getPreferredCanvasFormat() das passende Format.
  • writeTexture: Hier muss bytesPerRow nicht auf 256 aufgerundet werden, bei copyBufferToTexture() dagegen schon.
  • Kompatibilität: WebGPU ist nur in sicheren Kontexten verfügbar und noch nicht in allen Browsern bzw. auf allen Plattformen aktiviert. Vorher mit if (!navigator.gpu) prüfen.