Signatur
Beschreibung
Die Methode getPreferredCanvasFormat() des GPU-Interfaces (erreichbar über navigator.gpu) liefert das Texturformat, mit dem ein Canvas auf dem aktuellen System am effizientesten Inhalte mit 8-Bit-Farbtiefe und standardmäßigem Dynamikumfang (SDR) darstellt. Der Wert ist immer entweder "bgra8unorm" oder "rgba8unorm".
Gebraucht wird der Wert beim Konfigurieren eines GPUCanvasContext mit context.configure({ device, format }). Verwendest du ein Format, das nicht zum bevorzugten passt, muss der Browser beim Anzeigen jedes Frames eventuell eine zusätzliche Kopie oder Umwandlung machen. Das kostet Leistung und Speicherbandbreite.
Das zurückgegebene Format muss auch im targets-Array des Fragment-Stadiums deiner Render-Pipeline stehen (fragment.targets[i].format), damit die Pipeline zur Textur des Canvas passt. Die Methode läuft synchron und braucht weder Adapter noch Gerät. Du kannst sie also schon aufrufen, bevor requestAdapter() fertig ist.
Rückgabewert
GPUTextureFormat für Canvas-Kontexte auf dem aktuellen System.Beispiele
Canvas-Kontext mit bevorzugtem Format konfigurieren
const init = async () => {
if (!navigator.gpu) {
throw new Error('WebGPU wird nicht unterstützt');
}
const adapter = await navigator.gpu.requestAdapter();
if (!adapter) {
throw new Error('Kein passender GPU-Adapter gefunden');
}
const device = await adapter.requestDevice();
const canvas = document.querySelector('#gfx');
const context = canvas.getContext('webgpu');
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format, alphaMode: 'premultiplied' });
console.log('Canvas-Format:', format);
return { device, context, format };
};
init().catch(console.error);
Format in der Render-Pipeline verwenden
const createPipeline = (device, format) => {
const module = device.createShaderModule({
code: `
@vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
var pos = array<vec2f, 3>(vec2f(0.0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
return vec4f(pos[i], 0.0, 1.0);
}
@fragment fn fs() -> @location(0) vec4f {
return vec4f(1.0, 0.4, 0.0, 1.0);
}
`
});
return device.createRenderPipeline({
layout: 'auto',
vertex: { module, entryPoint: 'vs' },
fragment: {
module,
entryPoint: 'fs',
// Muss zum Format des Canvas-Kontexts passen
targets: [{ format }]
},
primitive: { topology: 'triangle-list' }
});
};
// Nutzung: const pipeline = createPipeline(device, navigator.gpu.getPreferredCanvasFormat());
Unterstützung prüfen und Format protokollieren
const preferredFormat = () =>
'gpu' in navigator ? navigator.gpu.getPreferredCanvasFormat() : null;
console.log(preferredFormat() ?? 'WebGPU nicht verfügbar');
// Wichtig · Fallstricke
- Nicht fest kodieren: Welches Format zurückkommt, hängt vom System ab. Unter Windows und macOS ist es meist
"bgra8unorm", unter Android oft"rgba8unorm". Schreib keinen der beiden Werte fest in den Code, sondern frag die Methode ab. - Gleiches Format überall: Das Format in
context.configure()und infragment.targetsder Pipeline muss übereinstimmen. Sonst meldet WebGPU einen Validierungsfehler, sobald du den Render-Pass ausführst. - Nur SDR mit 8 Bit: Für HDR oder mehr Farbtiefe (z. B.
"rgba16float"mittoneMapping: { mode: 'extended' }) ist die Methode nicht gedacht. - sRGB-Varianten: Ein
*-srgb-Format bekommst du über die OptionviewFormatsinconfigure(), z. B.viewFormats: [format + '-srgb'], und erzeugst damit die passende Texturansicht. - Kompatibilität: WebGPU gibt es nur in sicheren Kontexten (HTTPS). Es läuft in Chromium-Browsern ab Version 113, in Safari ab 26 und in Firefox ab 141 (zuerst unter Windows). Prüf vor der Nutzung immer, ob
navigator.gpuvorhanden ist. Die Methode gibt es auch in Web Workern überWorkerNavigator.gpu, zum Beispiel fürOffscreenCanvas.