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

GPUDevice.createRenderPipeline()

Methode

Erstellt synchron eine <code>GPURenderPipeline</code>, die Vertex- und Fragment-Shader-Stufen samt Rasterisierungs-, Tiefen- und Blend-Zustand für Render-Passes festlegt.

seit JavaScript WebGPU – Chrome/Edge 113+, Firefox 141+ (Windows), Kategorie: webapi

Signatur

GPUDevice.prototype.createRenderPipeline(descriptor)

Beschreibung

Mit createRenderPipeline() legst du fest, wie die GPU Geometrie verarbeitet und Pixel erzeugt. Eine Render-Pipeline bündelt den Vertex-Shader (samt Layout der Vertex-Buffer), den optionalen Fragment-Shader (samt Farbzielen und Blending), die Primitiv-Topologie (Dreiecke, Linien, Punkte), den Tiefen-/Stencil-Zustand und die Multisampling-Einstellungen in einem unveränderlichen Objekt.

Die fertige Pipeline wird in einem GPURenderPassEncoder oder GPURenderBundleEncoder per setPipeline() gesetzt, bevor du mit draw() oder drawIndexed() zeichnest. Pipelines erstellst du normalerweise einmal beim Initialisieren und verwendest sie in jedem Frame wieder – das Erzeugen ist teuer, weil die Shader dabei für die konkrete Hardware kompiliert werden.

Die Methode arbeitet synchron und liefert sofort ein Pipeline-Objekt zurück. Validierungsfehler werfen keine Ausnahme, sondern erzeugen eine ungültige Pipeline und einen GPUValidationError, den du über pushErrorScope()/popErrorScope() oder das uncapturederror-Ereignis abfängst. Wer das Blockieren des Hauptthreads vermeiden will, nutzt die asynchrone Variante createRenderPipelineAsync().

Parameter

Name Typ Default Beschreibung
$descriptor Pflicht GPURenderPipelineDescriptor Konfigurationsobjekt der Pipeline mit den folgenden Eigenschaften.
$descriptor.layout Pflicht GPUPipelineLayout | "auto" Das Pipeline-Layout mit den Bind-Group-Layouts. Mit "auto" wird das Layout aus den Shadern abgeleitet und ist über pipeline.getBindGroupLayout(index) abrufbar.
$descriptor.vertex Pflicht GPUVertexState Vertex-Stufe: module (GPUShaderModule), optional entryPoint, constants und buffers (Array aus GPUVertexBufferLayout mit arrayStride, stepMode und attributes).
$descriptor.fragment GPUFragmentState Fragment-Stufe: module, optional entryPoint, constants sowie targets (Array mit format, optional blend und writeMask). Weglassen ist z. B. für reine Tiefen-Passes (Shadow Maps) möglich.
$descriptor.primitive GPUPrimitiveState { topology: "triangle-list", frontFace: "ccw", cullMode: "none" } Topologie ("point-list", "line-list", "line-strip", "triangle-list", "triangle-strip"), stripIndexFormat, frontFace, cullMode und unclippedDepth (erfordert Feature).
$descriptor.depthStencil GPUDepthStencilState Tiefen-/Stencil-Zustand: format (z. B. "depth24plus"), depthWriteEnabled, depthCompare, Stencil-Operationen und Depth-Bias.
$descriptor.multisample GPUMultisampleState { count: 1, mask: 0xFFFFFFFF, alphaToCoverageEnabled: false } Multisampling-Einstellungen; count darf 1 oder 4 sein und muss zu den Render-Targets passen.
$descriptor.label string "" Bezeichnung für Fehlermeldungen und Debugging-Werkzeuge.

Rückgabewert

Typ
GPURenderPipeline
Beschreibung
Die neue Render-Pipeline. Bei Validierungsfehlern ist das Objekt ungültig, und es wird ein GPUValidationError ausgelöst.

Beispiele

Minimale Pipeline für ein Dreieck

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

const module = device.createShaderModule({
  code: `
    @vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
      let pos = array(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);
    }`
});

const pipeline = device.createRenderPipeline({
  label: 'Dreieck',
  layout: 'auto',
  vertex: { module, entryPoint: 'vs' },
  fragment: { module, entryPoint: 'fs', targets: [{ format }] }
});

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()]);
Ein oranges Dreieck wird auf das Canvas gezeichnet.

Vertex-Buffer-Layout, Tiefentest und Backface-Culling

const pipeline = device.createRenderPipeline({
  label: 'Mesh-Pipeline',
  layout: 'auto',
  vertex: {
    module,
    entryPoint: 'vs',
    buffers: [{
      arrayStride: 6 * 4, // 3 floats Position + 3 floats Normale
      attributes: [
        { shaderLocation: 0, offset: 0, format: 'float32x3' },
        { shaderLocation: 1, offset: 12, format: 'float32x3' }
      ]
    }]
  },
  fragment: {
    module,
    entryPoint: 'fs',
    targets: [{ format: navigator.gpu.getPreferredCanvasFormat() }]
  },
  primitive: { topology: 'triangle-list', cullMode: 'back' },
  depthStencil: {
    format: 'depth24plus',
    depthWriteEnabled: true,
    depthCompare: 'less'
  }
});

// Bind-Group-Layout aus dem automatischen Layout holen
const bindGroupLayout = pipeline.getBindGroupLayout(0);
console.log(bindGroupLayout.label);

Alpha-Blending und Fehlerbehandlung per Error-Scope

device.pushErrorScope('validation');

const pipeline = device.createRenderPipeline({
  layout: 'auto',
  vertex: { module, entryPoint: 'vs' },
  fragment: {
    module,
    entryPoint: 'fs',
    targets: [{
      format: 'bgra8unorm',
      blend: {
        color: { srcFactor: 'src-alpha', dstFactor: 'one-minus-src-alpha', operation: 'add' },
        alpha: { srcFactor: 'one', dstFactor: 'one-minus-src-alpha', operation: 'add' }
      }
    }]
  }
});

const error = await device.popErrorScope();
if (error) {
  console.error('Pipeline ungültig:', error.message);
} else {
  console.log('Pipeline erfolgreich erstellt');
}
Pipeline erfolgreich erstellt