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 方法中使用它,以便在渲染 pass 中发出绘制调用。请参阅以下代码段和问题 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();

着色器模块编译选项“严格的数学运算”

向 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() 方法现已移除。请参阅移除 intent

Dawn 更新

tint_benchmark 可执行文件用于衡量将着色器从 WGSL 翻译为每个后端语言的开销。如需了解详情,请参阅新的文档

本文仅介绍了一些主要亮点。查看详尽的提交内容列表

WebGPU 中的新变化

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

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