Neuerungen bei der WebGPU (Chrome 131)

François Beaufort
François Beaufort

Clip-Abstände in WGSL

Mit Begrenzungsabständen können Sie das Begrenzungsvolumen von Primitiven mit benutzerdefinierten Halbräumen in der Ausgabe der Vertex-Phase einschränken. Wenn Sie eigene Clipping-Ebenen definieren, haben Sie mehr Kontrolle darüber, was in Ihren WebGPU-Szenen sichtbar ist. Diese Technik ist besonders nützlich für Anwendungen wie CAD-Software, bei denen eine präzise Kontrolle der Visualisierung entscheidend ist.

Wenn die "clip-distances"-Funktion in einem GPUAdapter verfügbar ist, fordern Sie ein GPUDevice mit dieser Funktion an, um die Unterstützung von Schnittabständen in WGSL zu erhalten, und aktivieren Sie diese Erweiterung in Ihrem WGSL-Code mit enable clip_distances; explizit. Nach der Aktivierung können Sie das integrierte clip_distances-Array in Ihrem Vertex-Shader verwenden. Dieses Array enthält Entfernungen zu einer benutzerdefinierten Clippingebene:

  • Ein Schnittabstand von 0 bedeutet, dass sich der Eckpunkt auf der Ebene befindet.
  • Ein positiver Abstand bedeutet, dass sich der Eckpunkt innerhalb des Clip-Halbraums befindet (der Seite, die Sie behalten möchten).
  • Ein negativer Abstand bedeutet, dass sich der Eckpunkt außerhalb des Clip-Halbraums befindet (die Seite, die Sie verwerfen möchten).

Weitere Informationen finden Sie im folgenden Snippet, im chromestatus-Eintrag und in Problem 358408571.

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("clip-distances")) {
  throw new Error("Clip distances support is not available");
}
// Explicitly request clip distances support.
const device = await adapter.requestDevice({
  requiredFeatures: ["clip-distances"],
});

const vertexShaderModule = device.createShaderModule({ code: `
  enable clip_distances;

  struct VertexOut {
    @builtin(clip_distances) my_clip_distances : array<f32, 1>,
    @builtin(position) my_position : vec4f,
  }
  @vertex fn main() -> VertexOut {
    var output : VertexOut;
    output.my_clip_distances[0] = 1;
    output.my_position = vec4f(0, 0, 0, 1);
    return output;
  }
`,
});

// Send the appropriate commands to the GPU...

GPUCanvasContext getConfiguration()

Nachdem GPUCanvasContext configure() mit einem Konfigurations-Dictionary aufgerufen wurde, können Sie mit der Methode GPUCanvasContext getConfiguration() die Canvas-Kontextkonfiguration prüfen. Dazu gehören die Mitglieder device, format, usage, viewFormats, colorSpace, toneMapping und alphaMode. Das ist beispielsweise nützlich, um zu prüfen, ob der Browser HDR-Canvas unterstützt, wie im Beispiel „Partikel (HDR)“ gezeigt. Weitere Informationen finden Sie im folgenden Snippet, im chromestatus-Eintrag und in Problem 370109829.

const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const canvas = document.querySelector("canvas");
const context = canvas.getContext("webgpu");

// Configure the canvas for HDR.
context.configure({
  device,
  format: "rgba16float",
  toneMapping: { mode: "extended" },
});

const configuration = context.getConfiguration();
if (configuration.toneMapping.mode === "extended") {
  // The browser supports HDR canvas.
  // Warning! The user still needs a HDR display to enjoy HDR content.
}

Punkt- und Linienprimitive dürfen keine Tiefenverzerrung haben.

Wie bereits angekündigt, ist es gemäß der WebGPU-Spezifikation jetzt ein Validierungsfehler, wenn depthBias, depthBiasSlopeScale und depthBiasClamp auf einen Wert ungleich 0 gesetzt werden, wenn die Topologie einer Renderpipeline einen Linien- oder Punkttyp hat. Siehe Problem 352567424.

Integrierte Funktionen für inklusives Scannen von Untergruppen

Im Rahmen der Tests für Untergruppen wurden in Issue 361330160 die folgenden integrierten Funktionen für Untergruppen hinzugefügt:

  • subgroupInclusiveAdd(value): Gibt die inklusive Scansumme aller aktiven Aufrufe values in der Untergruppe zurück.
  • subgroupInclusiveMul(value): Gibt die inklusive Scanmultiplikation aller aktiven Aufrufe values in der Untergruppe zurück.

Experimentelle Unterstützung für indirekte Multi-Draw-Anzeigen

Mit der indirekten GPU-Funktion für mehrere Zeichnungen können Sie mehrere Draw-Aufrufe mit einem einzigen GPU-Befehl ausführen. Das ist besonders nützlich, wenn eine große Anzahl von Objekten gerendert werden muss, z. B. bei Partikelsystemen, Instanzen und großen Szenen. Die GPURenderPassEncoder-Methoden drawIndirect() und drawIndexedIndirect() können jeweils nur einen einzigen Draw-Aufruf aus einer bestimmten Region eines GPU-Buffers ausgeben.

Bis diese experimentelle Funktion standardisiert ist, aktivieren Sie das Flag „Unsafe WebGPU Support“ (Unterstützung für unsichere WebGPU) unter chrome://flags/#enable-unsafe-webgpu, um sie in Chrome verfügbar zu machen.

Wenn die nicht standardmäßige GPU-Funktion "chromium-experimental-multi-draw-indirect" in einem GPUAdapter verfügbar ist, fordern Sie ein GPUDevice mit dieser Funktion an. Erstellen Sie dann einen GPU-Buffer mit der Verwendung GPUBufferUsage.INDIRECT, um die Draw-Aufrufe zu speichern. Sie können sie später in den neuen Methoden multiDrawIndirect() und multiDrawIndexedIndirect() des GPURenderPassEncoders verwenden, um Draw-Aufrufe innerhalb eines Renderpasses auszuführen. Weitere Informationen finden Sie im folgenden Snippet und in Issue 356461286.

const adapter = await navigator.gpu.requestAdapter();
if (!adapter.features.has("chromium-experimental-multi-draw-indirect")) {
  throw new Error("Experimental multi-draw indirect support is not available");
}
// Explicitly request experimental multi-draw indirect support.
const device = await adapter.requestDevice({
  requiredFeatures: ["chromium-experimental-multi-draw-indirect"],
});

// Draw call have vertexCount, instanceCount, firstVertex, and firstInstance parameters.
const drawData = new Uint32Array([
  3, 1, 0, 0, // First draw call
  3, 1, 3, 0, // Second draw call
]);
// Create a buffer to store the draw calls.
const drawBuffer = device.createBuffer({
  size: drawData.byteLength,
  usage: GPUBufferUsage.INDIRECT | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(drawBuffer, 0, drawData);

// Create a render pipeline, a vertex buffer, and a render pass encoder...

// Inside a render pass, issue the draw calls.
myPassEncoder.setPipeline(myPipeline);
myPassEncoder.setVertexBuffer(0, myVertexBuffer);
myPassEncoder.multiDrawIndirect(drawBuffer, /*offset=*/ 0, /*maxDrawCount=*/ 2);
myPassEncoder.end();

Shader-Modul-Kompilierungsoption „Strict Math“

Dem GPUShaderModuleDescriptor wurde eine boolesche strictMath-Entwickleroption hinzugefügt, mit der Sie die strikte Mathematik während der Shadermodulkompilierung aktivieren oder deaktivieren können. Sie ist unter chrome://flags/#enable-webgpu-developer-features hinter dem Flag „WebGPU Developer Features“ verfügbar. Das bedeutet, dass sie nur für die Entwicklung gedacht ist. Siehe Problem 42241455.

Diese Option wird derzeit von Metal und Direct3D unterstützt. Wenn die strikte Mathematik deaktiviert ist, kann der Compiler Ihre Shader auf folgende Weise optimieren:

  • Die Möglichkeit von NaN- und Infinity-Werten wird ignoriert.
  • -0 wird als +0 behandelt.
  • Ersetzen der Division durch eine schnellere Multiplikation mit dem Kehrwert.
  • Umsortieren von Vorgängen basierend auf assoziativen und distributiven Eigenschaften.
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();

const code = `
  // Examines the bit pattern of the floating-point number to
  // determine if it represents a NaN according to the IEEE 754 standard.
  fn isNan(x : f32) -> bool {
    bool ones_exp = (bitcast<u32>(x) & 0x7f8) == 0x7f8;
    bool non_zero_sig = (bitcast<u32>(x) & 0x7ffff) != 0;
    return ones_exp && non_zero_sig;
  }
  // ...
`;

// Enable strict math during shader compilation.
const shaderModule = device.createShaderModule({ code, strictMath: true });

GPUAdapter-Methode „requestAdapterInfo()“ entfernen

Die asynchrone Methode „GPUAdapter requestAdapterInfo()“ ist redundant, da Sie GPUAdapterInfo bereits synchron über das Attribut „GPUAdapter info“ abrufen können. Daher wurde die nicht standardmäßige GPUAdapter-Methode requestAdapterInfo() entfernt. Weitere Informationen finden Sie unter Absicht zum Entfernen.

Dawn-Updates

Die ausführbare Datei tint_benchmark misst die Kosten für die Übersetzung von Shadern von WGSL in die einzelnen Backendsprachen. Weitere Informationen finden Sie in der neuen Dokumentation.

Dies sind nur einige der wichtigsten Highlights. Eine vollständige Liste der Commits

Das ist neu bei WebGPU

Eine Liste aller Themen, die in der Reihe Was ist neu in WebGPU behandelt wurden.

Chrome 131

Chrome 130

Chrome 129

Chrome 128

Chrome 127

Chrome 126

Chrome 125

Chrome 124

Chrome 123

Chrome 122

Chrome 121

Chrome 120

Chrome 119

Chrome 118

Chrome 117

Chrome 116

Chrome 115

Chrome 114

Chrome 113