Texture Mapping
A 64×64 "rgba8unorm" checkerboard is uploaded with writeTexture(). Each row is 256 bytes, which satisfies the rule that bytesPerRow is a multiple of 256. The sampler uses "nearest", so the cells stay sharp when magnified. The full explanation is in Textures and samplers.
Live demo
Section titled “Live demo”Checkerboard
Core code
Section titled “Core code”const size = 64;const bytesPerRow = 256;const pixels = new Uint8Array(bytesPerRow * size);// Fill two colors in 8×8 cells. The byte offset is y * bytesPerRow + x * 4.
const texture = device.createTexture({ size: [size, size], format: "rgba8unorm", usage: GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST,});device.queue.writeTexture( { texture }, pixels, { bytesPerRow }, { width: size, height: size },);
const sampler = device.createSampler({ magFilter: "nearest", minFilter: "nearest",});
const bindGroup = device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [ { binding: 0, resource: texture.createView() }, { binding: 1, resource: sampler }, ],});@group(0) @binding(0) var gradientTex: texture_2d<f32>;@group(0) @binding(1) var gradientSampler: sampler;
@fragmentfn fs_main(@location(0) uv: vec2f) -> @location(0) vec4f { return textureSample(gradientTex, gradientSampler, uv);}