Using GPU Textures
Texture Dimension
Most textures tend to be two dimensional textures, however GPUs can support additional configurations
Dimension | WebGPU | WebGL2 | Layout | Description |
---|---|---|---|---|
1d | ✅ | ❌ | TextureData | Contains a one dimensional texture (for compute) |
2d | ✅ | ✅ | TextureData | Contains a "normal" image texture |
2d-array | ✅ | ✅ | TextureData[] | Holds an "array" of 2D textures. |
3d | ✅ | ✅ | TextureData[] | Holds a "stack" of textures which enables 3D interpolation. |
cube | ✅ | ✅ | TextureData[6] | Holds 6 textures representing sides of a cube. |
cube-array | ✅ | ❌ | TextureData[6][] | Holds an array where every 6 textures represent the sides of a cube. |
Sometimes a composite texture can be used as a unit, but sometimes it is necessary to specify a specific subtexture.
Texture Formats
A "texture format" specifies which components (RGBA) are present in pixels, and how those pixels are stored in GPU memory. This is an important property of a GPU Texture which must be specified on Texture creation.
In luma.gl, texture formats are identified using string constants, and the TextureFormat
type can be used to ensure texture format strings are valid.
The following table lists all the texture formats constants supported by luma.gl (ordered by how many bytes each pixel occupies).
Note that even though a GPU supports creating and sampling textures of a certain format, additional capabilities may need to be checked separatey, more information below the table.
GPUs support a wide range of texture formats. In luma.gl, each format is identified with a string (the TextureFormat
type).
Texture Data
The textures may not be completely packed, there may be padding (per row)
Compressed Textures
Compressed textures refers to textures that are compressed in a way that can be decompressed performantly on the GPU during sampling. Such textures do not need to be decompressed fully (neither on CPU or GPU) but can be uploaded directly to the GPU in their compressed format, and will remain compressed there. There are some considerations when using compressed textures as support varies between devices, so assets must typically be prepared in multiple formats.
For more information, see e.g. Compressed Textures in 2020.
For supported compressed texture formats, see Texture Formats.
Supercompressed Textures
Supercompressed textures solve the portability problem of compressed textures by defining a common super-compressed format which can be decoded after load into a supported compressed texture format.
To use Basis supercompressed textures in luma.gl, see the loaders.gl BasisLoader
which can extract compressed textures from a basis encoded texture.
Texture creation
const texture = device.createTexture({});
Reading from Textures on the GPU (Sampling)
A primary purpose of textures is to allow the GPU to read from them.
vec4 texel = sampler2D(texture)
Texture filtering
Sampling is a sophisticated process
- magnification
- minification
- anistropy
The parameters used for sampling is specified in a sampler object.
Mipmaps
To improve samling mipmaps can be prepared.
Binding textures
Before textures can be sampled in the
Writing to Textures on the GPU
To write to textures on the GPU
Blending
Data Textures
In WebGPU/WGSL, textures can be used with compute shaders through storage bindings.
Copying Textures
Texture data can be copied between GPU and CPU and vice versa.
Texture Format Capabilities
Even though a device allows a Texture
to be created with a certain texture format, there may still be limitations in what operations can be done with that texture.
luma provides Device
methods to help applications determine the capabilities of a texture format.
Can textures with the format... | Check using |
---|---|
be created and sampled (using nearest filters)? | device.isTextureFormatSupported(format) |
be sampled using linear filtering? | device.isTextureFormatFilterable(format) |
be rendered into? (render targets / color attachments) | device.isTextureFormatRenderable(format) |
be used for storage bindings? | N/A |
be blended? | Yes, if sampler type float is supported |
support multisampling? | N/A |
Remarks
- Mipmaps can only be auto created for formats that are both filterable and renderable.
- A renderable format is either a color renderable format, or a depth-or-stencil format
- All depth/stencil formats are renderable.
- Samplers always read a "vec4" regardless of which texture format is used. For formats with less than 4 components, missing red, green and blue components in the texture format are read as
0.0
, alpha as1.0
/ - Note that some formats are not mandated by the base standard but represent additional capabilities (e.g. a WebGL2 device running on top of an OpenGL ES 3.2 driver). .