Says what 8-bit images hold: 'srgb' for colour, which sampling turns into linear light, or 'linear' for data such as normals, roughness or height.
mips?
boolean= true
Generates every mip level down to 1 × 1.
packed?
Unpack= none
Converts light stored in an 8-bit image, such as RGBM, to linear light once, at upload, so the texture filters and mips like any HDR texture.
format?
'rgba16float' | 'rg11b10ufloat'= 'rgba16float'
Sets the format of a texture of light, from packed or half-float images.
SamplerOptionssampler · 3 fields
wrap?
GPUAddressMode= 'repeat'
Says what happens past the edge: WebGPU's address mode on every axis.
filter?
GPUFilterMode= 'linear'
Filters within and between mip levels.
anisotropy?
number= 1
Sets the samples at grazing angles, 1 to 16.
submits
while setting up
create, array and cube generate mips with TypeGPU's generateMipmaps, which submits its own commands, unless mips is false. With packed, or a format other than the image's, they first draw each layer through a pipeline of their own and submit it.
owns
textures ·samplers ·a baker with `packed` or a narrower `format`
The textures and samplers each call returns, of which you destroy the textures; a staging texture it destroys and a baker that draws it into the texture, used once while creating.
One sand image on a plane to the horizon. Without mips, the distant sand turns grainy. At 1× anisotropy, it blurs where the ground is seen at a slant. Read as linear, the colour bytes come out washed out.
A WebGPU texture holds texels in a format, and an image file holds encoded bytes. Between them sit a decode, a choice of format that says whether the bytes are colour or data, an upload and the smaller copies sampling reads at a distance. images does each step, so a texture is two calls: decode while loading, then create.
Decodes an image file. A Radiance .hdr file, by its MIME type images.HDR, decodes with
decodeHdr on any thread. Other files decode with custom, or with decodeBitmap where
createImageBitmap exists. Rejects on a runtime without either.
@param ― image the encoded file and its MIME type
@param ― custom decodes files other than HDR, such as on a worker without createImageBitmap
Creates a sampled texture from one image. 8-bit images become rgba8unorm-srgb, or
rgba8unorm with color: 'linear'. Half-float images, and 8-bit ones with packed, become
format. Throws if the pixel count doesn't match the size, the image is empty or larger than
the device allows, packed comes with color, or format with 8-bit colour or data.
@param ― picture pixels from decode, decodeHdr or your own code, or a bitmap
@returns ― a texture you destroy, with every mip level unless mips is false
An 8-bit image holds either colour, which a screen showed in sRGB, or data, such as normals, roughness or height. Colour goes into an rgba8unorm-srgb texture, which sampling turns into linear light. Data goes into rgba8unorm with color: 'linear', which samples the bytes as they are:
Creates a sampled texture from one image. 8-bit images become rgba8unorm-srgb, or
rgba8unorm with color: 'linear'. Half-float images, and 8-bit ones with packed, become
format. Throws if the pixel count doesn't match the size, the image is empty or larger than
the device allows, packed comes with color, or format with 8-bit colour or data.
@param ― picture pixels from decode, decodeHdr or your own code, or a bitmap
@returns ― a texture you destroy, with every mip level unless mips is false
create(
constroot:TgpuRoot
root,
constpicture:images.Picture
picture,{
Options.color?:"srgb"|"linear"|undefined
Says what 8-bit images hold: 'srgb' for colour, which sampling turns into linear light, or
'linear' for data such as normals, roughness or height. Half-float images are linear
either way. Default 'srgb'.
Creates a sampled texture from one image. 8-bit images become rgba8unorm-srgb, or
rgba8unorm with color: 'linear'. Half-float images, and 8-bit ones with packed, become
format. Throws if the pixel count doesn't match the size, the image is empty or larger than
the device allows, packed comes with color, or format with 8-bit colour or data.
@param ― picture pixels from decode, decodeHdr or your own code, or a bitmap
@returns ― a texture you destroy, with every mip level unless mips is false
create(
constroot:TgpuRoot
root,
consticon:images.Picture
icon,{
Options.mips?: boolean |undefined
Generates every mip level down to 1 × 1. Default true.
mips:false});
Pixels you made yourself are a { width, height, pixels } with 4 bytes per pixel, unpremultiplied, in rows from the top. create takes them like a decoded file and throws if the count doesn’t match the size.
A Radiance .hdr file holds light brighter than white, such as a panorama of the sky with the sun in it. images.decodeHdr(bytes) decodes it into half floats, and create stores them in rgba16float:
Decodes a Radiance .hdr file into linear half floats for an rgba16float texture. It reads
flat and run-length encoded RGBE scanlines in the standard -Y +X order, and clamps values
above 65 504, a half float's largest. It runs on any thread, a React Native worker included.
Throws for another orientation, an XYZE file, a side above 16 384 or a truncated or corrupt
file.
Creates a sampled texture from one image. 8-bit images become rgba8unorm-srgb, or
rgba8unorm with color: 'linear'. Half-float images, and 8-bit ones with packed, become
format. Throws if the pixel count doesn't match the size, the image is empty or larger than
the device allows, packed comes with color, or format with 8-bit colour or data.
@param ― picture pixels from decode, decodeHdr or your own code, or a bitmap
@returns ― a texture you destroy, with every mip level unless mips is false
create(
constroot:TgpuRoot
root,
constmeadow:images.HdrImage
meadow);// rgba16float, linear
decode reads a file whose MIME type is images.HDR, image/vnd.radiance, the same way.
An environment bakes such a panorama into the light around a scene.
Values above 65 504, the largest half float, clamp to it. The sun in a photographed sky can be brighter.
The decoder reads flat and run-length encoded RGBE rows from the top, as Poly Haven and most tools write them. It throws for other orientations and for XYZE files.
Some HDR files store light in 8-bit channels. RGBM, for example, stores rgb × a × range. Sampling such a texture interpolates the stored values, which gives the wrong light between texels whose a differs. packed converts each texel to linear light once, when the texture is created:
Creates a sampled texture from one image. 8-bit images become rgba8unorm-srgb, or
rgba8unorm with color: 'linear'. Half-float images, and 8-bit ones with packed, become
format. Throws if the pixel count doesn't match the size, the image is empty or larger than
the device allows, packed comes with color, or format with 8-bit colour or data.
@param ― picture pixels from decode, decodeHdr or your own code, or a bitmap
@returns ― a texture you destroy, with every mip level unless mips is false
create(
constroot:TgpuRoot
root,
constpicture:images.Picture
picture,{
Options.packed?:images.Unpack|undefined
Converts light stored in an 8-bit image, such as RGBM, to linear light once, at upload, so the
texture filters and mips like any HDR texture. A 'use gpu' function that takes each texel as
stored, unfiltered, and returns linear RGBA. The texture takes format. It reads raw values,
so it takes no color. Default none.
packed:
import images
images.
constrgbm:(range:number)=>images.Unpack
Unpacks RGBM, light stored as rgb × a × range in linear values, for packed.
@param ― range the brightest light the encoding holds
Creates a sampled texture from one image. 8-bit images become rgba8unorm-srgb, or
rgba8unorm with color: 'linear'. Half-float images, and 8-bit ones with packed, become
format. Throws if the pixel count doesn't match the size, the image is empty or larger than
the device allows, packed comes with color, or format with 8-bit colour or data.
@param ― picture pixels from decode, decodeHdr or your own code, or a bitmap
@returns ― a texture you destroy, with every mip level unless mips is false
create(
constroot:TgpuRoot
root,
constpicture:images.Picture
picture,{
Options.packed?:images.Unpack|undefined
Converts light stored in an 8-bit image, such as RGBM, to linear light once, at upload, so the
texture filters and mips like any HDR texture. A 'use gpu' function that takes each texel as
stored, unfiltered, and returns linear RGBA. The texture takes format. It reads raw values,
so it takes no color. Default none.
packed:
import images
images.
constrgbm:(range:number)=>images.Unpack
Unpacks RGBM, light stored as rgb × a × range in linear values, for packed.
@param ― range the brightest light the encoding holds
Sets the format of a texture of light, from packed or half-float images.
'rg11b10ufloat' takes half the memory and drops alpha. It needs the device feature
'rg11b10ufloat-renderable'. 8-bit images without packed take the format color picks.
Default 'rgba16float'.
format:'rg11b10ufloat'});
packed is any 'use gpu' function from a stored texel to linear RGBA, and images.rgbm(range) is one. It reads the raw values, so it takes no color.
'rg11b10ufloat' takes half the memory and drops alpha. It needs the device feature 'rg11b10ufloat-renderable'.
images.array(root, pictures) makes a 2D array with one image per layer, such as terrain materials or an animation’s frames. All layers share a size and a kind. Sample a view of d.texture2dArray(d.f32) with the layer index.
images.cube(root, faces) makes a cube map from six square faces in WebGPU’s order: +x, −x, +y, −y, +z, −z. Sample a view of d.textureCube(d.f32) with a direction.
images.sampler(root, options) filters linearly within and between mip levels and repeats past the edge. wrap takes WebGPU’s address modes, such as 'clamp-to-edge'. anisotropy sharpens surfaces seen at grazing angles, up to 16 samples. WebGPU allows it only with linear filtering, so filter: 'nearest' uses one sample.
React Native’s createImageBitmap runs on the JS thread only, and a scene on a worker has none. Decode PNG, JPEG and WebP files on the JS thread with images.decodeBitmap, then pass the bitmaps to the scene, where create takes them. A Decode of your own, such as one built on Skia, can return { width, height, pixels } instead: pass it to decode as its second argument.
React Native’s decoder premultiplies alpha and then divides it back, so colour where alpha is near 0 is lost. It also ignores colorSpaceConversion: 'none', so a colour profile in the file can change the bytes. Keep data out of alpha here, or decode to pixels with your own Decode. For packed HDR, use an encoding that leaves alpha at 255 rather than RGBM, or a .hdr file.
decodeHdr is plain JavaScript and runs on any thread, the worker included.
Every image of an array or a cube has one size and one kind: 8-bit or half float.
create, array and cube submit to generate mips, and with packed to unpack. Call them while loading, not in a frame.
8-bit images keep 4 channels and half-float images keep 4 half floats per texel. A 2048 × 1024 HDR panorama takes 22 MB with its mips, and the same image in 8 bits takes 11 MB. A packed image takes the HDR size, or the 8-bit size in rg11b10ufloat.