Start · Sprachen · JavaScript · Referenz · GPURenderPassEncoder.setBlendConstant()

GPURenderPassEncoder.setBlendConstant()

Methode

Setzt die konstante Blendfarbe (RGBA), die bei den Blendfaktoren <code>"constant"</code> und <code>"one-minus-constant"</code> einer Render-Pipeline verwendet wird.

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

Signatur

GPURenderPassEncoder.prototype.setBlendConstant(color)

Beschreibung

Mit setBlendConstant() legst du für den laufenden Render-Durchgang eine konstante Farbe fest, auf die die Blend-Stufe zugreifen kann. Diese Konstante wird nur ausgewertet, wenn im blend-Abschnitt eines Farbziels im Pipeline-Deskriptor (fragment.targets[i].blend) als srcFactor oder dstFactor der Wert "constant" oder "one-minus-constant" steht.

Typische Anwendungsfälle sind Überblendungen mit einem festen Mischverhältnis (z. B. eine Szene zu 30 % über eine andere legen), Einfärben mit einer Tönungsfarbe oder das Ein- und Ausblenden ganzer Ebenen, ohne dafür einen Uniform-Buffer zu ändern oder die Pipeline neu zu erstellen. Weil die Konstante ein dynamischer Zustand des Encoders ist, kann dieselbe Pipeline mit verschiedenen Konstanten mehrfach im selben Durchgang benutzt werden.

Die Konstante gilt ab dem Aufruf für alle nachfolgenden Draw-Aufrufe im selben GPURenderPassEncoder, bis sie erneut gesetzt wird. Zu Beginn jedes Render-Durchgangs ist sie [0, 0, 0, 0]. Bei "constant" wird für die Farbkomponenten der RGB-Anteil und für den Alpha-Kanal der Alpha-Anteil der Konstante genutzt.

Parameter

Name Typ Default Beschreibung
$color Pflicht GPUColor (Array<number> der Länge 4 | {r: number, g: number, b: number, a: number}) Die Blendkonstante als Rot-, Grün-, Blau- und Alpha-Anteil, normalerweise im Bereich 0.0–1.0. Entweder als Array [r, g, b, a] oder als Objekt { r, g, b, a }.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Die Methode speichert den Befehl nur im Encoder; ausgeführt wird er erst, wenn der Command-Buffer an die Queue übergeben wird.

Beispiele

Pipeline mit konstantem Blendfaktor anlegen und Konstante setzen

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

const module = device.createShaderModule({
  code: `
    @vertex fn vs(@builtin(vertex_index) i: u32) -> @builtin(position) vec4f {
      var p = array(vec2f(0, 0.8), vec2f(-0.8, -0.8), vec2f(0.8, -0.8));
      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' },
  fragment: {
    module,
    entryPoint: 'fs',
    targets: [{
      format,
      blend: {
        // Ergebnis = Quelle * Konstante + Ziel * (1 - Konstante)
        color: { srcFactor: 'constant', dstFactor: 'one-minus-constant', operation: 'add' },
        alpha: { srcFactor: 'one', dstFactor: 'zero', operation: 'add' }
      }
    }]
  }
});

const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
  colorAttachments: [{
    view: context.getCurrentTexture().createView(),
    clearValue: [0, 0, 0.3, 1],
    loadOp: 'clear',
    storeOp: 'store'
  }]
});

pass.setPipeline(pipeline);
// Dreieck zu 40 % über den Hintergrund mischen
pass.setBlendConstant([0.4, 0.4, 0.4, 1]);
pass.draw(3);
pass.end();
device.queue.submit([encoder.finish()]);
Ein orangefarbenes Dreieck, das zu 40 % mit dem dunkelblauen Hintergrund gemischt ist.

Dieselbe Pipeline mit unterschiedlichen Konstanten zeichnen

// Annahme: pipeline, pass und vertexBuffer existieren bereits (siehe oben)
const opacities = [0.2, 0.5, 0.8];

pass.setPipeline(pipeline);
pass.setVertexBuffer(0, vertexBuffer);

opacities.forEach((o, i) => {
  // Objekt-Schreibweise ist ebenfalls erlaubt
  pass.setBlendConstant({ r: o, g: o, b: o, a: 1 });
  pass.draw(3, 1, i * 3); // jeweils ein anderes Dreieck
});
pass.end();
Drei Dreiecke mit 20 %, 50 % und 80 % Deckkraft – ohne Pipeline-Wechsel.

Animiertes Überblenden pro Frame

const frame = (time) => {
  const t = (Math.sin(time / 1000) + 1) / 2; // 0 … 1
  const encoder = device.createCommandEncoder();
  const pass = encoder.beginRenderPass({
    colorAttachments: [{
      view: context.getCurrentTexture().createView(),
      loadOp: 'clear', storeOp: 'store', clearValue: [0, 0, 0, 1]
    }]
  });
  pass.setPipeline(pipeline);
  pass.setBlendConstant([t, t, t, 1]); // Konstante muss in jedem Durchgang neu gesetzt werden
  pass.draw(3);
  pass.end();
  device.queue.submit([encoder.finish()]);
  requestAnimationFrame(frame);
};
requestAnimationFrame(frame);
Das Dreieck blendet weich ein und aus.

// Wichtig · Fallstricke

  • Wirkung nur mit passendem Blendfaktor: Ohne "constant" oder "one-minus-constant" im blend-Deskriptor der aktiven Pipeline hat der Aufruf keine sichtbare Wirkung.
  • Zurücksetzen pro Durchgang: Die Konstante wird bei jedem beginRenderPass() auf [0, 0, 0, 0] gesetzt. Wenn du sie vergisst, sieht die Quelle bei "constant" komplett transparent bzw. schwarz aus.
  • Werte außerhalb von 0–1: Bei normalisierten Formaten (z. B. bgra8unorm) wird auf den gültigen Bereich begrenzt. Nur Float-Ziele wie rgba16float können größere Werte sinnvoll nutzen.
  • Ein Array mit einer anderen Länge als 4 löst einen TypeError aus. Wenn der Encoder schon mit end() beendet wurde, entsteht ein Validierungsfehler.
  • Kompatibilität: WebGPU gibt es nur im sicheren Kontext. Die Unterstützung ist noch nicht in allen Browsern bzw. auf allen Plattformen vollständig. Prüfe daher vorher mit if (!navigator.gpu) und sieh eine Ausweichlösung vor.