Start · Sprachen · JavaScript · Referenz · GPUCommandEncoder.beginRenderPass()

GPUCommandEncoder.beginRenderPass()

Methode

Startet die Aufzeichnung eines Render-Passes und gibt einen <code>GPURenderPassEncoder</code> zurück, mit dem Zeichenbefehle für die angegebenen Farb- und Tiefen-Anhänge aufgezeichnet werden.

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

Signatur

GPUCommandEncoder.prototype.beginRenderPass(descriptor)

Beschreibung

beginRenderPass() eröffnet im GPUCommandEncoder einen Render-Pass. Das ist der Abschnitt, in dem die GPU mit Render-Pipelines in Texturen zeichnet. Über den Deskriptor legst du fest, wohin gezeichnet wird: in einen oder mehrere Farb-Anhänge (colorAttachments) und optional in einen Tiefen-/Stencil-Anhang (depthStencilAttachment). Außerdem bestimmst du, was am Anfang und am Ende des Passes mit den Inhalten geschieht: Mit loadOp werden sie geleert oder übernommen, mit storeOp gespeichert oder verworfen.

Der zurückgegebene GPURenderPassEncoder nimmt Befehle wie setPipeline(), setBindGroup(), setVertexBuffer() und draw() entgegen. Der Pass wird mit end() abgeschlossen. Erst danach kannst du den Command-Encoder weiterverwenden, etwa für einen weiteren Pass oder Kopierbefehle, oder ihn mit finish() in einen GPUCommandBuffer umwandeln und über device.queue.submit() absenden.

Typische Einsätze sind das Zeichnen eines Frames in den Canvas (über context.getCurrentTexture().createView()), das Rendern in eine Offscreen-Textur für Nachbearbeitungseffekte, Shadow-Maps (nur Tiefen-Anhang) und Multisampling mit resolveTarget.

Parameter

Name Typ Default Beschreibung
$descriptor Pflicht GPURenderPassDescriptor Objekt, das den Render-Pass beschreibt. Mögliche Felder:
  • colorAttachments (Pflicht, Array<GPURenderPassColorAttachment | null>): Jeder Eintrag enthält view (GPUTextureView), loadOp ("clear" | "load"), storeOp ("store" | "discard") sowie optional clearValue (z. B. { r, g, b, a } oder [r, g, b, a]), resolveTarget (für MSAA) und depthSlice (für 3D-Texturen).
  • depthStencilAttachment (optional): view, depthLoadOp, depthStoreOp, depthClearValue, depthReadOnly, stencilLoadOp, stencilStoreOp, stencilClearValue, stencilReadOnly.
  • occlusionQuerySet (optional, GPUQuerySet): Abfragesatz für Occlusion-Queries.
  • timestampWrites (optional): { querySet, beginningOfPassWriteIndex, endOfPassWriteIndex }. Setzt das Feature "timestamp-query" voraus.
  • maxDrawCount (optional, number, Standard 50000000): Obergrenze für die Zahl der Draw-Aufrufe.
  • label (optional, string): Name für Fehlermeldungen und Debugging.

Rückgabewert

Typ
GPURenderPassEncoder
Beschreibung
Ein Encoder, mit dem die Zeichenbefehle des Passes aufgezeichnet werden. Der Pass muss mit end() abgeschlossen werden.

Beispiele

Canvas mit einer Farbe leeren und ein Dreieck zeichnen

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 p = array(vec2f(0.0, 0.5), vec2f(-0.5, -0.5), vec2f(0.5, -0.5));
      return vec4f(p[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({
  layout: 'auto',
  vertex: { module, entryPoint: 'vs' },
  fragment: { module, entryPoint: 'fs', targets: [{ format }] }
});

const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
  label: 'Hauptpass',
  colorAttachments: [{
    view: context.getCurrentTexture().createView(),
    clearValue: { r: 0.1, g: 0.1, b: 0.15, a: 1 },
    loadOp: 'clear',
    storeOp: 'store'
  }]
});
pass.setPipeline(pipeline);
pass.draw(3);
pass.end();

device.queue.submit([encoder.finish()]);
Ein orangefarbenes Dreieck auf dunkelblauem Hintergrund im Canvas.

Render-Pass mit Tiefenpuffer

// Voraussetzung: device, context und format wie im ersten Beispiel
const depthTexture = device.createTexture({
  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: [0, 0, 0, 1],
    loadOp: 'clear',
    storeOp: 'store'
  }],
  depthStencilAttachment: {
    view: depthTexture.createView(),
    depthClearValue: 1.0,
    depthLoadOp: 'clear',
    depthStoreOp: 'store'
  }
});
// Die Pipeline braucht depthStencil: { format: 'depth24plus', depthCompare: 'less', depthWriteEnabled: true }
// pass.setPipeline(pipeline3D); pass.draw(vertexCount);
pass.end();
device.queue.submit([encoder.finish()]);

4×-Multisampling mit resolveTarget

const msaaTexture = device.createTexture({
  size: [canvas.width, canvas.height],
  sampleCount: 4,
  format,
  usage: GPUTextureUsage.RENDER_ATTACHMENT
});

const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
  colorAttachments: [{
    view: msaaTexture.createView(),               // Multisample-Ziel
    resolveTarget: context.getCurrentTexture().createView(), // geglättetes Ergebnis
    clearValue: [1, 1, 1, 1],
    loadOp: 'clear',
    storeOp: 'discard' // MSAA-Daten werden nach dem Auflösen nicht mehr gebraucht
  }]
});
// Die Pipeline braucht multisample: { count: 4 }
pass.end();
device.queue.submit([encoder.finish()]);