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 处启用“Unsafe WebGPU Support”标志,使其在 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 Developer Features”标志后面,这意味着它是一项仅供开发期间使用的功能。请参阅问题 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 147-148

Chrome 146

Chrome 145

Chrome 144

Chrome 143

Chrome 142

Chrome 141

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