WebGPU 的新变化 (Chrome 131)

François Beaufort
François Beaufort

WGSL 中的剪裁距离

通过剪裁距离,您可以在顶点阶段的输出中,使用用户定义的半空间来限制图元剪裁量。通过定义自己的裁剪平面,您可以更好地控制 WebGPU 场景中的可见内容。此技术对于 CAD 软件等应用尤其有用,因为在这些应用中,对可视化的精确控制至关重要。

当 GPUAdapter 中提供 "clip-distances" 功能时,请求具有此功能的 GPUDevice 以在 WGSL 中获得剪裁距离支持,并使用 enable clip_distances; 在 WGSL 代码中显式启用此扩展。启用后,您可以在顶点着色器中使用 clip_distances 内置数组。此数组包含到用户定义的裁剪平面的距离:

  • 裁剪距离为 0 表示顶点位于平面上。
  • 正距离表示顶点位于剪裁半空间(您要保留的一侧)内。
  • 负距离表示顶点位于裁剪半空间(您要舍弃的一侧)之外。

请参阅以下代码段、chromestatus 条目问题 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()

使用配置字典调用 GPUCanvasContext configure() 后,您可以使用 GPUCanvasContext getConfiguration() 方法检查画布上下文配置。它包括 deviceformatusageviewFormatscolorSpacetoneMappingalphaMode 成员。这对于检查浏览器是否支持 HDR 画布等任务非常有用,如粒子(HDR)示例中所示。请参阅以下代码段、chromestatus 条目问题 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.
}

点和线图元不得具有深度偏移

正如之前所宣布的那样,WebGPU 规范现在规定,当渲染流水线的拓扑为线或点类型时,将 depthBiasdepthBiasSlopeScaledepthBiasClamp 设置为非零值会导致验证错误。请参阅问题 352567424

面向子群组的包容性扫描内置函数

作为子群组实验的一部分,问题 361330160 中添加了以下子群组内置函数:

  • subgroupInclusiveAdd(value):返回子群组中所有有效调用 value 的包含性扫描总和。
  • subgroupInclusiveMul(value):返回子群组中所有有效调用 value 的包含性扫描乘积。

对多重绘制间接提供了实验性支持

借助多重间接绘制 GPU 功能,您只需发出一个 GPU 命令即可发出多个绘制调用。在需要渲染大量对象(例如粒子系统、实例化和大场景)的情况下,这尤其有用。drawIndirect()drawIndexedIndirect() GPURenderPassEncoder 方法一次只能从 GPU 缓冲区的某个区域发出一个绘制调用。

在这一实验性功能标准化之前,请在 chrome://flags/#enable-unsafe-webgpu 处启用“不安全的 WebGPU 支持”标志,以便在 Chrome 中使用该功能。

如果 GPUAdapter 中有 "chromium-experimental-multi-draw-indirect" 非标准 GPU 功能,请请求具有此功能的 GPUDevice。然后,创建一个具有 GPUBufferUsage.INDIRECT 用途的 GPUBuffer 来存储绘制调用。您可以在新的 multiDrawIndirect()multiDrawIndexedIndirect() GPURenderPassEncoder 方法中使用它,以在渲染通道内发出绘制调用。请参阅以下代码段和问题 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();

着色器模块编译选项 strict math

已向 GPUShaderModuleDescriptor 添加布尔值 strictMath 开发者选项,以便您在着色器模块编译期间启用或停用严格数学模式。它位于 chrome://flags/#enable-webgpu-developer-features 的“WebGPU 开发者功能”标志后面,这意味着它是一项仅供开发期间使用的功能。请参阅问题 42241455

此选项目前在 Metal 和 Direct3D 上受支持。如果停用严格数学模式,编译器可能会通过以下方式优化着色器:

  • 忽略 NaN 和 Infinity 值。
  • 将 -0 视为 +0。
  • 用倒数相乘来代替除法,从而加快运算速度。
  • 根据结合律和分配律重新排列运算。
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 requestAdapterInfo()

GPUAdapter requestAdapterInfo() 异步方法是冗余的,因为您已经可以使用 GPUAdapter info 属性同步获取 GPUAdapterInfo。因此,现在移除了非标准的 GPUAdapter requestAdapterInfo() 方法。请参阅移除意向

Dawn 更新

tint_benchmark 可执行文件用于衡量将着色器从 WGSL 转换为每种后端语言的成本。如需详细了解此功能,请参阅新文档

这仅涵盖了部分重要亮点。查看详尽的提交列表

WebGPU 的新变化

WebGPU 新变化系列中涵盖的所有内容的列表。

Chrome 140

Chrome 139

Chrome 138

Chrome 137

Chrome 136

Chrome 135

Chrome 134

Chrome 133

Chrome 132

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