Signatur
Beschreibung
Die Eigenschaft format des Interfaces GPUTexture gibt das Texelformat der Textur zurück, also wie jedes Texel im Speicher aufgebaut ist: Anzahl und Reihenfolge der Kanäle, Bittiefe pro Kanal und Datentyp (z. B. unorm, float, uint, srgb). Der Wert entspricht dem Feld format aus dem Deskriptor, der an GPUDevice.createTexture() übergeben wurde. Bei Texturen aus GPUCanvasContext.getCurrentTexture() entspricht er dem Format, das in context.configure() gesetzt wurde.
Gebraucht wird die Eigenschaft vor allem in generischem Code, der Texturen von außen bekommt. Typische Fälle sind Hilfsfunktionen für Mipmap-Erzeugung, Blit- oder Post-Processing-Durchläufe. Dort muss das Format im fragment.targets einer Render-Pipeline genau zum Format der Zieltextur passen. Ebenso muss man beim Kopieren mit writeTexture() oder copyBufferToTexture() aus dem Format die richtige bytesPerRow berechnen.
Der Wert ist ein String aus der Aufzählung GPUTextureFormat. Beispiele sind Farbformate ("bgra8unorm", "rgba16float"), Tiefen-/Stencil-Formate ("depth24plus-stencil8", "depth32float") und komprimierte Formate ("bc1-rgba-unorm", "astc-4x4-unorm"), wobei die komprimierten nur mit aktivierten Features verfügbar sind. Nach dem Erzeugen der Textur lässt sich das Format nicht mehr ändern.
Rückgabewert
GPUTextureFormat, z. B. "rgba8unorm", "bgra8unorm" oder "depth24plus". Die Eigenschaft ist schreibgeschützt.Beispiele
Format einer neu erzeugten Textur auslesen
const adapter = await navigator.gpu?.requestAdapter();
if (!adapter) throw new Error('WebGPU nicht verfügbar');
const device = await adapter.requestDevice();
const texture = device.createTexture({
size: [256, 256],
format: 'rgba8unorm',
usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST
});
console.log(texture.format);
Pipeline passend zum Format der Canvas-Textur erzeugen
const canvas = document.querySelector('canvas');
const context = canvas.getContext('webgpu');
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();
context.configure({
device,
format: navigator.gpu.getPreferredCanvasFormat()
});
const target = context.getCurrentTexture();
console.log('Canvas-Format:', target.format);
const module = device.createShaderModule({
code: `
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
let p = array(vec2f(0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
return vec4f(p[i], 0, 1);
}
@fragment fn fs() -> @location(0) vec4f { return vec4f(1, 0.5, 0, 1); }
`
});
const pipeline = device.createRenderPipeline({
layout: 'auto',
vertex: { module, entryPoint: 'vs' },
// Zielformat MUSS dem Texturformat entsprechen
fragment: { module, entryPoint: 'fs', targets: [{ format: target.format }] }
});
bytesPerRow abhängig vom Format berechnen
// Bytes pro Texel für einige unkomprimierte Formate
const BYTES_PER_TEXEL = {
r8unorm: 1,
rg8unorm: 2,
rgba8unorm: 4,
'rgba8unorm-srgb': 4,
bgra8unorm: 4,
rgba16float: 8,
rgba32float: 16
};
const uploadPixels = (device, texture, data) => {
const bpt = BYTES_PER_TEXEL[texture.format];
if (!bpt) throw new Error(`Format ${texture.format} nicht unterstützt`);
device.queue.writeTexture(
{ texture },
data,
{ bytesPerRow: texture.width * bpt },
[texture.width, texture.height]
);
};
// Aufruf, z. B.:
// uploadPixels(device, texture, new Uint8Array(256 * 256 * 4));
// Wichtig · Fallstricke
- Schreibgeschützt: Eine Zuweisung an
texture.formatwird stillschweigend ignoriert (im Strict Mode gibt es einenTypeError). Für ein anderes Format erzeugt man eine neue Textur. Mit dem DeskriptorfeldviewFormatskann man stattdessen Views in kompatiblen Formaten anlegen (z. B."rgba8unorm-srgb"zu"rgba8unorm"). - Canvas-Format ist plattformabhängig:
navigator.gpu.getPreferredCanvasFormat()liefert meist"bgra8unorm", auf manchen Systemen (z. B. Android) aber"rgba8unorm". Deshalb das Format besser zur Laufzeit überformatabfragen, statt es fest einzutragen. - Komprimierte Formate und Tiefenformate: Bei Formaten wie
"bc7-rgba-unorm"arbeitet man mit Blöcken statt einzelnen Texeln.bytesPerRowbezieht sich dann auf Blockzeilen."depth24plus"hat keine festgelegte Bytegröße und kann nicht direkt kopiert werden. - Kompatibilität: WebGPU steht nur in sicheren Kontexten (HTTPS) zur Verfügung. Die Unterstützung ist noch nicht in allen Browsern vollständig (Firefox und Safari erst in neueren Versionen und nicht auf allen Plattformen). Vorher mit
navigator.gpuprüfen, ob die API vorhanden ist.