Start · Sprachen · JavaScript · Referenz · GPUShaderModule

GPUShaderModule

Schnittstelle

Repräsentiert ein kompiliertes WGSL-Shader-Modul der WebGPU API, das in Render- oder Compute-Pipelines als Vertex-, Fragment- oder Compute-Stufe verwendet wird.

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

Signatur

interface GPUShaderModule

Beschreibung

GPUShaderModule ist ein Container für Shader-Code in der Sprache WGSL (WebGPU Shading Language). Ein Modul wird nicht direkt über einen Konstruktor erzeugt, sondern über GPUDevice.createShaderModule({ code }). Der Browser prüft und übersetzt den WGSL-Code dabei in das native Format der Grafikschnittstelle (Vulkan, Metal oder Direct3D 12).

Ein Modul kann mehrere Einstiegspunkte enthalten, z. B. eine mit @vertex, eine mit @fragment und eine mit @compute markierte Funktion. Bei GPUDevice.createRenderPipeline() oder createComputePipeline() verweist man dann über module und entryPoint auf die passende Funktion. So lässt sich ein Modul in mehreren Pipelines wiederverwenden.

Die Schnittstelle hat nur wenige Mitglieder:

  • label (Eigenschaft): ein frei wählbarer Name, der in Fehlermeldungen und Debugging-Werkzeugen angezeigt wird.
  • getCompilationInfo() (Methode): gibt ein Promise<GPUCompilationInfo> zurück. Dessen Array messages enthält Fehler, Warnungen und Hinweise des Compilers, jeweils mit Zeile, Spalte und Text.

createShaderModule() wirft keine Ausnahme, wenn der Code fehlerhaft ist. Das Modul wird dann als ungültig markiert, und der Fehler zeigt sich erst später. Deshalb sollte man während der Entwicklung getCompilationInfo() auswerten oder mit pushErrorScope('validation') arbeiten.

Parameter

Name Typ Default Beschreibung
$descriptor.code Pflicht string WGSL-Quelltext des Moduls (Übergabe an GPUDevice.createShaderModule()).
$descriptor.label string "" Optionaler Name für Fehlermeldungen und Debugging-Werkzeuge. Man kann ihn später über module.label lesen und ändern.
$descriptor.compilationHints Array<{ entryPoint: string, layout?: GPUPipelineLayout | "auto" }> [] Optionale Hinweise auf Einstiegspunkte und Pipeline-Layouts. Der Browser kann damit früher kompilieren.
$descriptor.sourceMap object Optionale Source Map für die Fehlersuche. Wird in der Praxis kaum unterstützt.

Rückgabewert

Typ
GPUShaderModule
Beschreibung
GPUDevice.createShaderModule() gibt ein GPUShaderModule zurück. Das Modul kann auch ungültig sein; dann hilft getCompilationInfo() bei der Fehlersuche.

Beispiele

Shader-Modul erzeugen und Compiler-Meldungen prüfen

const adapter = await navigator.gpu?.requestAdapter();
if (!adapter) throw new Error('WebGPU wird nicht unterstützt');
const device = await adapter.requestDevice();

const module = device.createShaderModule({
  label: 'Dreieck-Shader',
  code: /* wgsl */ `
    @vertex
    fn vs_main(@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_main() -> @location(0) vec4f {
      return vec4f(1.0, 0.4, 0.0, 1.0);
    }
  `
});

const info = await module.getCompilationInfo();
console.log(module.label, '–', info.messages.length, 'Meldungen');
Dreieck-Shader – 0 Meldungen

Modul in einer Render-Pipeline verwenden

const canvas = document.querySelector('canvas');
const context = canvas.getContext('webgpu');
const format = navigator.gpu.getPreferredCanvasFormat();
context.configure({ device, format });

// module aus dem vorherigen Beispiel: ein Modul, zwei Einstiegspunkte
const pipeline = device.createRenderPipeline({
  layout: 'auto',
  vertex: { module, entryPoint: 'vs_main' },
  fragment: { module, entryPoint: 'fs_main', targets: [{ format }] },
  primitive: { topology: 'triangle-list' }
});

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'
  }]
});
pass.setPipeline(pipeline);
pass.draw(3);
pass.end();
device.queue.submit([encoder.finish()]);

WGSL-Fehler mit Zeilenangabe ausgeben

const broken = device.createShaderModule({
  label: 'Kaputter Compute-Shader',
  code: `
    @compute @workgroup_size(64)
    fn main() {
      let x: f32 = 1; // Fehler: kein automatisches Umwandeln von i32 nach f32
    }
  `
});

const { messages } = await broken.getCompilationInfo();
for (const m of messages) {
  console.log(`[${m.type}] Zeile ${m.lineNum}:${m.linePos} – ${m.message}`);
}
[error] Zeile 4:20 – cannot initialize let of type 'f32' with value of type 'abstract-int' (Text je nach Browser unterschiedlich)

Validierungsfehler über einen Error-Scope abfangen

device.pushErrorScope('validation');
const mod = device.createShaderModule({ code: 'fn oops( {' });
const error = await device.popErrorScope();
if (error) {
  console.error('Shader ungültig:', error.message);
}
Shader ungültig: ... (browserabhängige Meldung)

// Wichtig · Fallstricke

  • Kein Konstruktor: new GPUShaderModule() wirft einen TypeError. Module werden immer über GPUDevice.createShaderModule() erzeugt.
  • Stille Fehler: Fehlerhafter WGSL-Code löst beim Erzeugen keine Ausnahme aus. Der Fehler zeigt sich erst als Validierungsfehler, z. B. beim Erstellen der Pipeline. Deshalb während der Entwicklung immer getCompilationInfo() oder pushErrorScope() nutzen.
  • Nur WGSL: GLSL und SPIR-V werden nicht direkt angenommen. Dafür braucht man einen Übersetzer wie naga oder tint.
  • Zeilennummern: lineNum und linePos beginnen bei 1. Die Positionen zählen UTF-16-Codeeinheiten, das ist bei Unicode-Kommentaren zu beachten.
  • Performance: Das Kompilieren kann teuer sein. Module sollten daher einmal erzeugt und wiederverwendet werden, nicht in jedem Frame. Für asynchrones Erstellen von Pipelines gibt es createRenderPipelineAsync().
  • Kompatibilität: WebGPU steht nur in sicheren Kontexten (HTTPS) zur Verfügung. Unterstützt wird es in Chrome/Edge ab 113, in Safari ab 26 und in Firefox ab 141 (zunächst unter Windows). Vorher unbedingt navigator.gpu prüfen. Auch in Web Workern ist die API verfügbar.
  • Sicherheit: Die GPU führt Shader-Code aus. Deshalb niemals ungeprüften WGSL-Code von Nutzern ausführen, weil das zu Denial-of-Service durch Endlosschleifen oder Geräteverlust führen kann (device.lost).