Texture
Quick answer
Texture stores sampling data and can also serve as a render target. Size and format are fixed at creation through device.createTexture({width, height, format, usage, mipLevels}), while contents change via writeData or render passes. Its default Sampler controls filtering when it is bound for sampling.
device. createTexture ( props ) → Texture
Key points
- format accepts 'rgba8unorm', 'rgba16float', 'r8unorm' and depth formats.
- Usage flags decide sampling, storage and render-attachment rights.
- writeData uploads typed arrays or image sources after creation.
Example
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: Texture.SAMPLE | Texture.COPY_DST,
sampler: {
minFilter: 'linear',
magFilter: 'linear',
mipmapFilter: 'none',
addressModeU: 'repeat',
addressModeV: 'repeat'
}
});
texture.writeData(pixels);const model = new Model(device, {
vs: vsSource,
fs: [
'#version 300 es',
'precision highp float;',
'in vec2 vUV;',
'uniform sampler2D uTexture;',
'out vec4 fragColor;',
'void main() {',
' fragColor = texture(uTexture, vUV);',
'}'
].join('\n'),
attributes: { positions: positions, uvs: uvs },
bufferLayout: [
{ name: 'positions', stepMode: 'vertex', format: 'float32x3' },
{ name: 'uvs', stepMode: 'vertex', format: 'float32x2' }
],
bindings: { uTexture: texture }
});
Notes
- Rendering into a texture without the attachment usage flag throws.
- Declared mipLevels above one require every level written or sampling reads black.
English edition written for Atlaslog. Code is taken from the original Chinese page and runs unchanged.
Atlaslog (2026). Texture. https://www.jingweizhi.com/en/lumagl/api/texture.html (accessed 2026-11-03).