v146 · Web APIs · WebGPU · WGSL
WebGPU texture and sampler lets
Chrome 146 adds support for declaring textures and samplers as local let variables in WGSL shaders. Previously these could only be declared as module-scope vars bound to specific binding groups. The new syntax enables more flexible shader code patterns.
concepts
-
Texture Lets Demo
A WebGPU shader that uses texture and sampler
letdeclarations — samples a texture into a local variable and uses it across the fragment shader without repeating the binding group syntax. -
WGSL Syntax
Side-by-side WGSL before and after: the old module-scope
varpattern vs the newletdeclarations, with examples of helper functions that accept textures as parameters. -
Binding tagger playground
Paste WGSL, hit "rewrite", get the 146-style version that aliases bindings into
lets. The meter shows how many binding declarations the lets remove. -
Sampler Gallery
Six sampler configurations — nearest vs linear filter, clamp/repeat/mirror-repeat address modes — rendered on a checkerboard texture. Demonstrates how WGSL texture/sampler
letbindings enable concise reuse of the same texture across multiple sample calls.
why it shipped
WGSL previously required textures and samplers to be declared at module scope as var bindings. This made it difficult to write reusable shader functions that take a texture as an argument, or to alias a texture with a local name inside a function. Chrome 146 allows texture and sampler handles to be stored in let variables and passed as function parameters, enabling cleaner, more composable shader code.
the change
// WGSL — before Chrome 146 (module-scope var only)
@group(0) @binding(0) var myTex: texture_2d<f32>;
@group(0) @binding(1) var mySampler: sampler;
@fragment fn main(@location(0) uv: vec2f) -> @location(0) vec4f {
// Must reference module-level names directly
return textureSample(myTex, mySampler, uv);
}
// WGSL — Chrome 146+ (texture/sampler let variables)
@group(0) @binding(0) var myTex: texture_2d<f32>;
@group(0) @binding(1) var mySampler: sampler;
fn sampleAt(tex: texture_2d<f32>, smp: sampler, uv: vec2f) -> vec4f {
return textureSample(tex, smp, uv);
}
@fragment fn main(@location(0) uv: vec2f) -> @location(0) vec4f {
// Local let alias
let t = myTex;
let s = mySampler;
return sampleAt(t, s, uv); // pass as parameters
}