Clip distances in WGSL
Clip distances allow you to restrict primitives' clip volume with user-defined half-spaces in the output of vertex stage. Defining your own clipping planes gives greater control over what's visible in your WebGPU scenes. This technique is particularly useful for applications like CAD software, where precise control over visualization is crucial.
When the "clip-distances"
feature is available in a GPUAdapter, request a GPUDevice with this feature to get clip distances support in WGSL, and explicitly enable this extension in your WGSL code with enable clip_distances;
. Once enabled, you can use the clip_distances
built-in array in your vertex shader. This array holds distances to a user-defined clip plane:
- A clip distance of 0 means the vertex lies on the plane.
- A positive distance means the vertex is inside the clip half-space (the side you want to keep).
- A negative distance means the vertex is outside the clip half-space (the side you want to discard).
See the following snippet, the chromestatus entry, and issue 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()
Once GPUCanvasContext configure()
has been called with a configuration dictionary, the GPUCanvasContext getConfiguration()
method lets you check the canvas context configuration. It includes device
, format
, usage
, viewFormats
, colorSpace
, toneMapping
, and alphaMode
members. This is useful for tasks like checking if the browser supports HDR canvas, as shown in the Particles (HDR) sample. See the following snippet, the chromestatus entry, and issue 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.
}
Point and line primitives must not have depth bias
As announced previously, the WebGPU spec now makes it a validation error to set depthBias
, depthBiasSlopeScale
, and depthBiasClamp
to a non-zero value when the topology for a render pipeline is a line or point type. See issue 352567424.
Inclusive scan built-in functions for subgroups
As part of the subgroups experimentation, the following subgroup built-in functions have been added in issue 361330160:
subgroupInclusiveAdd(value)
: Returns the inclusive scan summation of all active invocationsvalue
s across the subgroup.subgroupInclusiveMul(value)
: Returns the inclusive scan multiplication of all active invocationsvalue
s across the subgroup.
Experimental support for multi-draw indirect
The multi-draw indirect GPU feature lets you issue multiple draw calls with a single GPU command. This is particularly useful in situations where a large number of objects need to be rendered, such as particle systems, instancing, and large scenes. The drawIndirect()
and drawIndexedIndirect()
GPURenderPassEncoder methods can only issue a single draw call at a time from a certain region of a GPU buffer.
Until this experimental feature is standardized, enable the "Unsafe WebGPU Support" flag at chrome://flags/#enable-unsafe-webgpu
to make it available in Chrome.
With the "chromium-experimental-multi-draw-indirect"
non-standard GPU feature available in a GPUAdapter, request a GPUDevice with this feature. Then create a GPUBuffer with the GPUBufferUsage.INDIRECT
usage to store the draw calls. You can use it later in the new multiDrawIndirect()
and multiDrawIndexedIndirect()
GPURenderPassEncoder methods to issue draw calls inside a render pass. See the following snippet and 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 module compilation option strict math
A boolean strictMath
developer option has been added to GPUShaderModuleDescriptor to let you enable or disable strict math during shader module compilation. It is available behind the "WebGPU Developer Features" flag at chrome://flags/#enable-webgpu-developer-features
, which means it is a feature intended only for use during development. See issue 42241455.
This option is currently supported on Metal and Direct3D. When strict math is disabled, the compiler may optimize your shaders by:
- Ignoring the possibility of NaN and Infinity values.
- Treating -0 as +0.
- Replacing division with faster multiplication by the reciprocal.
- Rearranging operations based on associative and distributive properties.
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 });
Remove GPUAdapter requestAdapterInfo()
The GPUAdapter requestAdapterInfo()
asynchronous method is redundant as you can already get GPUAdapterInfo synchronously using the GPUAdapter info
attribute. Hence, the non-standard GPUAdapter requestAdapterInfo()
method is now removed. See the intent to remove.
Dawn updates
The tint_benchmark
executable measures the cost of translating shaders from WGSL to each backend language. Check out the new documentation to learn more about it.
This covers only some of the key highlights. Check out the exhaustive list of commits.
What's New in WebGPU
A list of everything that has been covered in the What's New in WebGPU series.
Chrome 131
- Clip distances in WGSL
- GPUCanvasContext getConfiguration()
- Point and line primitives must not have depth bias
- Inclusive scan built-in functions for subgroups
- Experimental support for multi-draw indirect
- Shader module compilation option strict math
- Remove GPUAdapter requestAdapterInfo()
- Dawn updates
Chrome 130
- Dual source blending
- Shader compilation time improvements on Metal
- Deprecation of GPUAdapter requestAdapterInfo()
- Dawn updates
Chrome 129
Chrome 128
- Experimenting with subgroups
- Deprecate setting depth bias for lines and points
- Hide uncaptured error DevTools warning if preventDefault
- WGSL interpolate sampling first and either
- Dawn updates
Chrome 127
- Experimental support for OpenGL ES on Android
- GPUAdapter info attribute
- WebAssembly interop improvements
- Improved command encoder errors
- Dawn updates
Chrome 126
- Increase maxTextureArrayLayers limit
- Buffer upload optimization for Vulkan backend
- Shader compilation time improvements
- Submitted command buffers must be unique
- Dawn updates
Chrome 125
Chrome 124
- Read-only and read-write storage textures
- Service workers and shared workers support
- New adapter information attributes
- Bug fixes
- Dawn updates
Chrome 123
- DP4a built-in functions support in WGSL
- Unrestricted pointer parameters in WGSL
- Syntax sugar for dereferencing composites in WGSL
- Separate read-only state for stencil and depth aspects
- Dawn updates
Chrome 122
- Expand reach with compatibility mode (feature in development)
- Increase maxVertexAttributes limit
- Dawn updates
Chrome 121
- Support WebGPU on Android
- Use DXC instead of FXC for shader compilation on Windows
- Timestamp queries in compute and render passes
- Default entry points to shader modules
- Support display-p3 as GPUExternalTexture color space
- Memory heaps info
- Dawn updates
Chrome 120
- Support for 16-bit floating-point values in WGSL
- Push the limits
- Changes to depth-stencil state
- Adapter information updates
- Timestamp queries quantization
- Spring-cleaning features
Chrome 119
- Filterable 32-bit float textures
- unorm10-10-10-2 vertex format
- rgb10a2uint texture format
- Dawn updates
Chrome 118
- HTMLImageElement and ImageData support in
copyExternalImageToTexture()
- Experimental support for read-write and read-only storage texture
- Dawn updates
Chrome 117
- Unset vertex buffer
- Unset bind group
- Silence errors from async pipeline creation when device is lost
- SPIR-V shader module creation updates
- Improving developer experience
- Caching pipelines with automatically generated layout
- Dawn updates
Chrome 116
- WebCodecs integration
- Lost device returned by GPUAdapter
requestDevice()
- Keep video playback smooth if
importExternalTexture()
is called - Spec conformance
- Improving developer experience
- Dawn updates
Chrome 115
- Supported WGSL language extensions
- Experimental support for Direct3D 11
- Get discrete GPU by default on AC power
- Improving developer experience
- Dawn updates
Chrome 114
- Optimize JavaScript
- getCurrentTexture() on unconfigured canvas throws InvalidStateError
- WGSL updates
- Dawn updates