Textures and samplers
Quick answer
This tutorial separates textures, which hold pixels on the GPU, from samplers, which define how those pixels are read. It creates a Sampler with linear filters, repeat address modes and anisotropy, builds an rgba8unorm Texture, and fills it with writeData or copyExternalImage for images and video frames. It binds the texture through bindings using the shader's sampler2D name and shows a texture used as both sample source and render target. Readers can upload imagery without blur, tiling artifacts or cross-origin failures.
Key points
- Set minFilter, magFilter and mipmapFilter to linear for smooth sampling.
- Upload pixels with texture.writeData instead of the removed data option.
- Bind textures through bindings using the shader's sampler2D name.
Example
const sampler = device.createSampler({
minFilter: 'linear',
magFilter: 'linear',
mipmapFilter: 'linear', // 需要纹理带 mipmap
addressModeU: 'repeat',
addressModeV: 'repeat',
maxAnisotropy: 4
});
console.log(sampler.props.addressModeU); // 'repeat'const SIZE = 64;
const pixels = new Uint8Array(SIZE * SIZE * 4);
for (let y = 0; y < SIZE; y++) {
for (let x = 0; x < SIZE; x++) {
const i = (y * SIZE + x) * 4;
const cell = ((x >> 3) + (y >> 3)) & 1;
pixels[i] = cell ? 232 : 52;
pixels[i + 1] = cell ? 186 : 118;
pixels[i + 2] = cell ? 84 : 214;
pixels[i + 3] = 255;
}
}
const texture = device.createTexture({
width: SIZE,
height: SIZE,
format: 'rgba8unorm',
usage: luma.Texture.SAMPLE | luma.Texture.COPY_DST,
sampler: sampler
});
texture.writeData(pixels);
Notes
- setSampler resets omitted fields to defaults instead of keeping previous values.
- Non-power-of-two textures break repeat and mipmaps unless they are clamped.
English edition written for Atlaslog. Code is taken from the original Chinese page and runs unchanged.
Atlaslog (2026). Textures and samplers. https://www.jingweizhi.com/en/lumagl/tutorials/textures-samplers.html (accessed 2026-11-03).