luma.gl/docs/api-reference/core/texture-formats.mdx
2023-08-18 17:52:53 -04:00

326 lines
52 KiB
Plaintext

import {DeviceTabs, Format as Ft, Filter as L, Render as R} from '@site/src/react-luma';
# Texture Formats
:::caution
The luma.gl v9 API is currently in [public review](/docs/public-review) and may be subject to change.
:::
The term "texture format" here refers to how pixels are stored in memory, which 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.
## Formats
| `TextureFormat` | Available | Filterable | Renderable | Notes / WebGL counterpart |
| ------------------------------------- | ----------------------------------- | ---------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **1 byte per pixel formats** | |
| `r8unorm` | <Ft f="r8unorm" /> | <L f="r8unorm" /> | <R f="r8unorm" /> | `GL.R8` |
| `r8snorm` | <Ft f="r8snorm" /> | <L f="r8snorm" /> | <R f="r8snorm" /> | `GL.R8_SNORM` |
| `r8uint` | <Ft f="r8uint" /> | <L f="r8uint" /> | <R f="r8uint" /> | `GL.R8UI` |
| `r8sint` | <Ft f="r8sint" /> | <L f="r8sint" /> | <R f="r8sint" /> | `GL.R8I` |
| **2 bytes per pixel formats** | |
| `r16uint` | <Ft f="r16uint" /> | <L f="r16uint" /> | <R f="r16uint" /> | `GL.R16UI` |
| `r16sint` | <Ft f="r16sint" /> | <L f="r16sint" /> | <R f="r16sint" /> | `GL.R16I` |
| `r16unorm-webgl` | <Ft f="r16unorm-webgl" /> | <L f="r16unorm-webgl" /> | <R f="r16unorm-webgl" /> | `GL.R16_EXT` `EXT_texture_norm16` |
| `r16snorm-webgl` | <Ft f="r16snorm-webgl" /> | <L f="r16snorm-webgl" /> | <R f="r16snorm-webgl" /> | `GL.R16_SNORM_EXT` `EXT_texture_norm16` |
| `r16float` | <Ft f="r16float" /> | <L f="r16float" /> | <R f="r16float" /> | `GL.R16F` |
| `rg8unorm` | <Ft f="rg8unorm" /> | <L f="rg8unorm" /> | <R f="rg8unorm" /> | `GL.RG8` |
| `rg8snorm` | <Ft f="rg8snorm" /> | <L f="rg8snorm" /> | <R f="rg8snorm" /> | |
| `rg8uint` | <Ft f="rg8uint" /> | <L f="rg8uint" /> | <R f="rg8uint" /> | `GL.RG8UI` |
| `rg8sint` | <Ft f="rg8sint" /> | <L f="rg8sint" /> | <R f="rg8sint" /> | `GL.RG8I` |
| **Packed 2 bytes per pixel formats** | |
| `rgba4norm-webgl` | <Ft f="rgba4norm-webgl" /> | <L f="rgba4norm-webgl" /> | <R f="rgba4norm-webgl" /> | `GL.RGBA4` |
| `rgb565norm-webgl` | <Ft f="rgb565norm-webgl" /> | <L f="rgb565norm-webgl" /> | <R f="rgb565norm-webgl" /> | `GL.RGB565` |
| `rgb5a1norm-webgl` | <Ft f="rgb5a1norm-webgl" /> | <L f="rgb5a1norm-webgl" /> | <R f="rgb5a1norm-webgl" /> | `GL.RGB5_A1` |
| **3 bytes per pixel formats** | |
| `rbg8norm-webgl` | <Ft f="rbg8norm-webgl" /> | <L f="rbg8norm-webgl" /> | <R f="rbg8norm-webgl" /> | `GL.RGB8` |
| **4 bytes per pixel formats** | |
| `r32uint` | <Ft f="r32uint" /> | <L f="r32uint" /> | <R f="r32uint" /> | `GL.R32UI` |
| `r32sint` | <Ft f="r32sint" /> | <L f="r32sint" /> | <R f="r32sint" /> | `GL.R32I` |
| `r32float` | <Ft f="r32float" /> | <L f="r32float" /> | <R f="r32float" /> | `GL.R32F` |
| `rg16uint` | <Ft f="rg16uint" /> | <L f="rg16uint" /> | <R f="rg16uint" /> | `GL.RG16UI` |
| `rg16sint` | <Ft f="rg16sint" /> | <L f="rg16sint" /> | <R f="rg16sint" /> | `GL.RG16I` |
| `rg16unorm-webgl` | <Ft f="rg16unorm-webgl" /> | <L f="rg16unorm-webgl" /> | <R f="rg16unorm-webgl" /> | |
| `rg16snorm-webgl` | <Ft f="rg16snorm-webgl" /> | <L f="rg16snorm-webgl" /> | <R f="rg16snorm-webgl" /> | |
| `rg16float` | <Ft f="rg16float" /> | <L f="rg16float" /> | <R f="rg16float" /> | `GL.RG16F` |
| `rgba8unorm` | <Ft f="rgba8unorm" /> | <L f="rgba8unorm" /> | <R f="rgba8unorm" /> | `GL.RGBA8` |
| `rgba8unorm-srgb` | <Ft f="rgba8unorm-srgb" /> | <L f="rgba8unorm-srgb" /> | <R f="rgba8unorm-srgb" /> | `GL.SRGB8_ALPHA8` |
| `rgba8snorm` | <Ft f="rgba8snorm" /> | <L f="rgba8snorm" /> | <R f="rgba8snorm" /> | |
| `rgba8uint` | <Ft f="rgba8uint" /> | <L f="rgba8uint" /> | <R f="rgba8uint" /> | `GL.RGBA8UI` |
| `rgba8sint` | <Ft f="rgba8sint" /> | <L f="rgba8sint" /> | <R f="rgba8sint" /> | `GL.RGBA8I` |
| `bgra8unorm` | <Ft f="bgra8unorm" /> | <L f="bgra8unorm" /> | <R f="bgra8unorm" /> | |
| `bgra8unorm-srgb` | <Ft f="bgra8unorm-srgb" /> | <L f="bgra8unorm-srgb" /> | <R f="bgra8unorm-srgb" /> | |
| **Packed 4 bytes per pixel formats** | | | |
| `rgb9e5ufloat` | <Ft f="rgb9e5ufloat" /> | <L f="rgb9e5ufloat" /> | <R f="rgb9e5ufloat" /> | `GL.RGB9_E5` |
| `rg11b10ufloat` | <Ft f="rg11b10ufloat" /> | <L f="rg11b10ufloat" /> | <R f="rg11b10ufloat" /> | `GL.R11F_G11F_B10F` |
| `rgb10a2unorm` | <Ft f="rgb10a2unorm" /> | <L f="rgb10a2unorm" /> | <R f="rgb10a2unorm" /> | `GL.RGB10_A2` |
| `rgb10a2unorm-webgl` | <Ft f="rgb10a2unorm-webgl" /> | <L f="rgb10a2unorm-webgl" /> | <R f="rgb10a2unorm-webgl" /> | `GL.RGB10_A2UI` |
| **6 bytes per pixel formats** | | | |
| `rgb16unorm-webgl` | <Ft f="rgb16unorm-webgl" /> | <L f="rgb16unorm-webgl" /> | <R f="rgb16unorm-webgl" /> | |
| `rgb16snorm-webgl` | <Ft f="rgb16snorm-webgl" /> | <L f="rgb16snorm-webgl" /> | <R f="rgb16snorm-webgl" /> | |
| **8 bytes per pixel formats** | | }} |
| `rg32uint` | <Ft f="rg32uint" /> | <L f="rg32uint" /> | <R f="rg32uint" /> | `GL.RG32UI` |
| `rg32sint` | <Ft f="rg32sint" /> | <L f="rg32sint" /> | <R f="rg32sint" /> | `GL.RG32I` |
| `rg32float` | <Ft f="rg32float" /> | <L f="rg32float" /> | <R f="rg32float" /> | `GL.RG32F` |
| `rgba16uint` | <Ft f="rgba16uint" /> | <L f="rgba16uint" /> | <R f="rgba16uint" /> | `GL.RGBA16UI` |
| `rgba16sint` | <Ft f="rgba16sint" /> | <L f="rgba16sint" /> | <R f="rgba16sint" /> | `GL.RGBA16I` |
| `rgba16unorm-webgl` | <Ft f="rgba16unorm-webgl" /> | <L f="rgba16unorm-webgl" /> | <R f="rgba16unorm-webgl" /> | |
| `rgba16snorm-webgl` | <Ft f="rgba16snorm-webgl" /> | <L f="rgba16snorm-webgl" /> | <R f="rgba16snorm-webgl" /> | |
| `rgba16float` | <Ft f="rgba16float" /> | <L f="rgba16float" /> | <R f="rgba16float" /> | `GL.RGBA16F` |
| **12 bytes per pixel formats** | | | |
| `rgb32float-webgl` | <Ft f="rgb32float-webgl" /> | <L f="rgb32float-webgl" /> | <R f="rgb32float-webgl" /> | `GL.RGB32F` Deprecated format. |
| **16 bytes per pixel formats** | | | |
| `rgba32uint` | <Ft f="rgba32uint" /> | <L f="rgba32uint" /> | <R f="rgba32uint" /> | |
| `rgba32sint` | <Ft f="rgba32sint" /> | <L f="rgba32sint" /> | <R f="rgba32sint" /> | |
| `rgba32float` | <Ft f="rgba32float" /> | <L f="rgba32float" /> | <R f="rgba32float" /> | |
| **Depth and stencil formats** | |
| `stencil8` | <Ft f="stencil8" /> | <L f="stencil8" /> | <R f="stencil8" /> | Platform dependent: Might use `depth24stencil8` with hidden depth. |
| `depth16unorm` | <Ft f="depth16unorm" /> | <L f="depth16unorm" /> | <R f="depth16unorm" /> | |
| `depth24plus` | <Ft f="depth24plus" /> | <L f="depth24plus" /> | <R f="depth24plus" /> | Platform dependent: Maps to "`depth24unorm`" or `depth32float`. |
| `depth24plus-stencil81` | <Ft f="depth24plus-stencil8" /> | <L f="depth24plus-stencil8" /> | <R f="depth24plus-stencil8" /> | Platform dependent: Maps to "`depth24unorm`" or `depth32float`. |
| `depth32float` | <Ft f="depth32float" /> | <L f="depth32float" /> | <R f="depth32float" /> | Higher precision than `depth24unorm` in representable range (0.0 to 1.0) |
| `depth24unorm-stencil8` | <Ft f="depth24unorm-stencil8" /> | <L f="depth24unorm-stencil8" /> | <R f="depth24unorm-stencil8" /> | Platform dependent: Check via `depth24unorm-stencil8` feature. |
| `depth32float-stencil8` | <Ft f="depth32float-stencil8" /> | <L f="depth32float-stencil8" /> | <R f="depth32float-stencil8" /> | Platform dependent: Check via `depth32float-stencil8` feature. |
| **`texture-compression-bc(5)`** | | | | _[S3 Texture Compression][s3tc_wiki], aka BC (Block Compression) using FourCC DXTn file identifiers. 4-6x compression._ |
| `bc1-rgb-unorm-webgl` | <Ft f="bc1-rgb-unorm-webgl" /> | <L f="bc1-rgb-unorm-webgl" /> | <R f="bc1-rgb-unorm-webgl" /> | BC1 / DXT1: 16 input pixels in 64 bits. |
| `bc1-rgb-unorm-srgb-webgl` | <Ft f="bc1-rgb-unorm-srgb-webgl" /> | <L f="bc1-rgb-unorm-srgb-webgl" /> | <R f="bc1-rgb-unorm-srgb-webgl" /> | |
| `bc1-rgba-unorm` | <Ft f="bc1-rgba-unorm" /> | <L f="bc1-rgba-unorm" /> | <R f="bc1-rgba-unorm" /> | |
| `bc1-rgba-unorm-srgb` | <Ft f="bc1-rgba-unorm-srgb" /> | <L f="bc1-rgba-unorm-srgb" /> | <R f="bc1-rgba-unorm-srgb" /> | |
| `bc2-rgba-unorm` | <Ft f="bc2-rgba-unorm" /> | <L f="bc2-rgba-unorm" /> | <R f="bc2-rgba-unorm" /> | BC2 / DXT3: 16 input pixels in 128 bits |
| `bc2-rgba-unorm-srgb` | <Ft f="bc2-rgba-unorm-srgb" /> | <L f="bc2-rgba-unorm-srgb" /> | <R f="bc2-rgba-unorm-srgb" /> | |
| `bc3-rgba-unorm` | <Ft f="bc3-rgba-unorm" /> | <L f="bc3-rgba-unorm" /> | <R f="bc3-rgba-unorm" /> | BC3 / DXT5: as BC2 with interpolated alpha. |
| `bc3-rgba-unorm-srgb` | <Ft f="bc3-rgba-unorm-srgb" /> | <L f="bc3-rgba-unorm-srgb" /> | <R f="bc3-rgba-unorm-srgb" /> | |
| `bc4-r-unorm` | <Ft f="bc4-r-unorm" /> | <L f="bc4-r-unorm" /> | <R f="bc4-r-unorm" /> | BC4: 16 input single-channel (e.g. greyscale) pixels into 64 bits of output. |
| `bc4-r-snorm` | <Ft f="bc4-r-snorm" /> | <L f="bc4-r-snorm" /> | <R f="bc4-r-snorm" /> | |
| `bc5-rg-unorm` | <Ft f="bc5-rg-unorm" /> | <L f="bc5-rg-unorm" /> | <R f="bc5-rg-unorm" /> | |
| `bc5-rg-snorm` | <Ft f="bc5-rg-snorm" /> | <L f="bc5-rg-snorm" /> | <R f="bc5-rg-snorm" /> | |
| **`texture-compression-bc`** | | | |
| `bc6h-rgb-ufloat` | <Ft f="bc6h-rgb-ufloat" /> | <L f="bc6h-rgb-ufloat" /> | <R f="bc6h-rgb-ufloat" /> | BC6H: 6 input RGB HDR (float16) pixels into 128 bits of output |
| `bc6h-rgb-float` | <Ft f="bc6h-rgb-float" /> | <L f="bc6h-rgb-float" /> | <R f="bc6h-rgb-float" /> | |
| `bc7-rgba-unorm` | <Ft f="bc7-rgba-unorm" /> | <L f="bc7-rgba-unorm" /> | <R f="bc7-rgba-unorm" /> | BC7: encodes 16 input RGB8/RGBA8 pixels into 128 bits of output |
| `bc7-rgba-unorm-srgb` | <Ft f="bc7-rgba-unorm-srgb" /> | <L f="bc7-rgba-unorm-srgb" /> | <R f="bc7-rgba-unorm-srgb" /> | |
| **`texture-compression-etc2`**` | | | | Performance caveat: Often CPU decompressed. |
| `etc2-rgb8unorm` | <Ft f="etc2-rgb8unorm" /> | <L f="etc2-rgb8unorm" /> | <R f="etc2-rgb8unorm" /> | `GL.COMPRESSED_RGB8_ETC2` |
| `etc2-rgb8unorm-srgb` | <Ft f="etc2-rgb8unorm-srgb" /> | <L f="etc2-rgb8unorm-srgb" /> | <R f="etc2-rgb8unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ETC2` |
| `etc2-rgb8a1unorm` | <Ft f="etc2-rgb8a1unorm" /> | <L f="etc2-rgb8a1unorm" /> | <R f="etc2-rgb8a1unorm" /> | `GL.COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2` |
| `etc2-rgb8a1unorm-srgb` | <Ft f="etc2-rgb8a1unorm-srgb" /> | <L f="etc2-rgb8a1unorm-srgb" /> | <R f="etc2-rgb8a1unorm-srgb" /> | `GL.COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2` |
| `etc2-rgba8unorm` | <Ft f="etc2-rgba8unorm" /> | <L f="etc2-rgba8unorm" /> | <R f="etc2-rgba8unorm" /> | `GL.COMPRESSED_RGBA8_ETC2_EAC` |
| `etc2-rgba8unorm-srgb` | <Ft f="etc2-rgba8unorm-srgb" /> | <L f="etc2-rgba8unorm-srgb" /> | <R f="etc2-rgba8unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC` |
| `eac-r11unorm` | <Ft f="eac-r11unorm" /> | <L f="eac-r11unorm" /> | <R f="eac-r11unorm" /> | `GL.COMPRESSED_R11_EAC` |
| `eac-r11snorm` | <Ft f="eac-r11snorm" /> | <L f="eac-r11snorm" /> | <R f="eac-r11snorm" /> | `GL.COMPRESSED_SIGNED_R11_EAC` |
| `eac-rg11unorm` | <Ft f="eac-rg11unorm" /> | <L f="eac-rg11unorm" /> | <R f="eac-rg11unorm" /> | `GL.COMPRESSED_RG11_EAC` |
| `eac-rg11snorm` | <Ft f="eac-rg11snorm" /> | <L f="eac-rg11snorm" /> | <R f="eac-rg11snorm" /> | `GL.COMPRESSED_SIGNED_RG11_EAC` |
| **`texture-compression-astc`**` | | | | X_ASTC compressed formats device.features.has |
| `astc-4x4-unorm` | <Ft f="astc-4x4-unorm" /> | <L f="astc-4x4-unorm" /> | <R f="astc-4x4-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_4x4_KHR` |
| `astc-4x4-unorm-srgb` | <Ft f="astc-4x4-unorm-srgb" /> | <L f="astc-4x4-unorm-srgb" /> | <R f="astc-4x4-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR` |
| `astc-5x4-unorm` | <Ft f="astc-5x4-unorm" /> | <L f="astc-5x4-unorm" /> | <R f="astc-5x4-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_5x4_KHR` |
| `astc-5x4-unorm-srgb` | <Ft f="astc-5x4-unorm-srgb" /> | <L f="astc-5x4-unorm-srgb" /> | <R f="astc-5x4-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR` |
| `astc-5x5-unorm` | <Ft f="astc-5x5-unorm" /> | <L f="astc-5x5-unorm" /> | <R f="astc-5x5-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_5x5_KHR` |
| `astc-5x5-unorm-srgb` | <Ft f="astc-5x5-unorm-srgb" /> | <L f="astc-5x5-unorm-srgb" /> | <R f="astc-5x5-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR` |
| `astc-6x5-unorm` | <Ft f="astc-6x5-unorm" /> | <L f="astc-6x5-unorm" /> | <R f="astc-6x5-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_6x5_KHR` |
| `astc-6x5-unorm-srgb` | <Ft f="astc-6x5-unorm-srgb" /> | <L f="astc-6x5-unorm-srgb" /> | <R f="astc-6x5-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR` |
| `astc-6x6-unorm` | <Ft f="astc-6x6-unorm" /> | <L f="astc-6x6-unorm" /> | <R f="astc-6x6-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_6x6_KHR` |
| `astc-6x6-unorm-srgb` | <Ft f="astc-6x6-unorm-srgb" /> | <L f="astc-6x6-unorm-srgb" /> | <R f="astc-6x6-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR` |
| `astc-8x5-unorm` | <Ft f="astc-8x5-unorm" /> | <L f="astc-8x5-unorm" /> | <R f="astc-8x5-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_8x5_KHR` |
| `astc-8x5-unorm-srgb` | <Ft f="astc-8x5-unorm-srgb" /> | <L f="astc-8x5-unorm-srgb" /> | <R f="astc-8x5-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR` |
| `astc-8x6-unorm` | <Ft f="astc-8x6-unorm" /> | <L f="astc-8x6-unorm" /> | <R f="astc-8x6-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_8x6_KHR` |
| `astc-8x6-unorm-srgb` | <Ft f="astc-8x6-unorm-srgb" /> | <L f="astc-8x6-unorm-srgb" /> | <R f="astc-8x6-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR` |
| `astc-8x8-unorm` | <Ft f="astc-8x8-unorm" /> | <L f="astc-8x8-unorm" /> | <R f="astc-8x8-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_8x8_KHR` |
| `astc-8x8-unorm-srgb` | <Ft f="astc-8x8-unorm-srgb" /> | <L f="astc-8x8-unorm-srgb" /> | <R f="astc-8x8-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR` |
| `astc-10x5-unorm` | <Ft f="astc-10x5-unorm" /> | <L f="astc-10x5-unorm" /> | <R f="astc-10x5-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_10x10_KHR` |
| `astc-10x5-unorm-srgb` | <Ft f="astc-10x5-unorm-srgb" /> | <L f="astc-10x5-unorm-srgb" /> | <R f="astc-10x5-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR` |
| `astc-10x6-unorm` | <Ft f="astc-10x6-unorm" /> | <L f="astc-10x6-unorm" /> | <R f="astc-10x6-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_10x6_KHR` |
| `astc-10x6-unorm-srgb` | <Ft f="astc-10x6-unorm-srgb" /> | <L f="astc-10x6-unorm-srgb" /> | <R f="astc-10x6-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR` |
| `astc-10x8-unorm` | <Ft f="astc-10x8-unorm" /> | <L f="astc-10x8-unorm" /> | <R f="astc-10x8-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_10x8_KHR` |
| `astc-10x8-unorm-srgb` | <Ft f="astc-10x8-unorm-srgb" /> | <L f="astc-10x8-unorm-srgb" /> | <R f="astc-10x8-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR` |
| `astc-10x10-unorm` | <Ft f="astc-10x10-unorm" /> | <L f="astc-10x10-unorm" /> | <R f="astc-10x10-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_10x10_KHR` |
| `astc-10x10-unorm-srgb` | <Ft f="astc-10x10-unorm-srgb" /> | <L f="astc-10x10-unorm-srgb" /> | <R f="astc-10x10-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR` |
| `astc-12x10-unorm` | <Ft f="astc-12x10-unorm" /> | <L f="astc-12x10-unorm" /> | <R f="astc-12x10-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_12x10_KHR` |
| `astc-12x10-unorm-srgb` | <Ft f="astc-12x10-unorm-srgb" /> | <L f="astc-12x10-unorm-srgb" /> | <R f="astc-12x10-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR` |
| `astc-12x12-unorm` | <Ft f="astc-12x12-unorm" /> | <L f="astc-12x12-unorm" /> | <R f="astc-12x12-unorm" /> | `GL.COMPRESSED_RGBA_ASTC_12x12_KHR` |
| `astc-12x12-unorm-srgb` | <Ft f="astc-12x12-unorm-srgb" /> | <L f="astc-12x12-unorm-srgb" /> | <R f="astc-12x12-unorm-srgb" /> | `GL.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR` |
| **`texture-compression-pvrtc-webgl`** | | | | `WEBGL_compressed_texture_pvrtc` |
| `pvrtc-rgb4unorm-webgl` | <Ft f="pvrtc-rgb4unorm-webgl" /> | <L f="pvrtc-rgb4unorm-webgl" /> | <R f="pvrtc-rgb4unorm-webgl" /> | `GL.COMPRESSED_RGB_PVRTC_4BPPV1_IMG` |
| `pvrtc-rgba4unorm-webgl` | <Ft f="pvrtc-rgba4unorm-webgl" /> | <L f="pvrtc-rgba4unorm-webgl" /> | <R f="pvrtc-rgba4unorm-webgl" /> | `GL.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG` |
| `pvrtc-rbg2unorm-webgl` | <Ft f="pvrtc-rbg2unorm-webgl" /> | <L f="pvrtc-rbg2unorm-webgl" /> | <R f="pvrtc-rbg2unorm-webgl" /> | `GL.COMPRESSED_RGB_PVRTC_2BPPV1_IMG` |
| `pvrtc-rgba2unorm-webgl` | <Ft f="pvrtc-rgba2unorm-webgl" /> | <L f="pvrtc-rgba2unorm-webgl" /> | <R f="pvrtc-rgba2unorm-webgl" /> | `GL.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG` |
| **`texture-compression-etc1-webgl`** |
| `etc1-rbg-unorm-webgl` | <Ft f="etc1-rbg-unorm-webgl" /> | <L f="etc1-rbg-unorm-webgl" /> | <R f="etc1-rbg-unorm-webgl" /> | `GL.COMPRESSED_RGB_ETC1_WEBGL` |
| **`texture-compression-pvrtc-webgl`** |
| `atc-rgb-unorm-webgl` | <Ft f="atc-rgb-unorm-webgl" /> | <L f="atc-rgb-unorm-webgl" /> | <R f="atc-rgb-unorm-webgl" /> | `GL.COMPRESSED_RGB_ATC_WEBGL` |
| `atc-rgba-unorm-webgl` | <Ft f="atc-rgba-unorm-webgl" /> | <L f="atc-rgba-unorm-webgl" /> | <R f="atc-rgba-unorm-webgl" /> | `GL.COMPRESSED_RGBA_ATC_EXPLICIT_ALPHA_WEBGL` |
| `atc-rgbai-unorm-webgl` | <Ft f="atc-rgbai-unorm-webgl" /> | <L f="atc-rgbai-unorm-webgl" /> | <R f="atc-rgbai-unorm-webgl" /> | `GL.COMPRESSED_RGBA_ATC_INTERPOLATED_ALPHA_WEBGL` |
[s3tc_wiki]: https://en.wikipedia.org/wiki/S3_Texture_Compression
## Texture Format detection
While a subset of texture formats are supported on all devices of a certain type, many texture formats are only supported if the underlying hardware supports them.
You can use `device.isTextureFormatSupported(format)` check if it is possible to create and sample textures with a specific texture format on your current device.
## 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 as `1.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). .
- WebGL 1 is very limited and does not provide sized formats (though extensions are often avialble). Unsized formats do give the GPU some freedom to select the most performant internal representation.
## Texture Format Groups
Support for some types of texture formats come in groups. As an alternative to checking texture support format-by-format,
[`Device.features`](./device-features) can be queried to determine if specific groups or classes of texture formats are supported.
| Feature | Optional capabilities |
| ------------------------------------- | --------------------------------------------------------- |
| `texture-srgb-webgl1` | sRGB formats are supported |
| `texture-depth-webgl` | depth texture formats are supported |
| `texture-float32-webgl` | Create floating point textures (`nearest` sampling only) |
| `texture-float16-webgl` | Create half-floating point textures (`nearest` sampling) |
| `texture-renderable-float32-webgl` | Floating point textures are color-renderable and readable |
| `texture-renderable-float15-webgl` | Half float textures are color-renderable and readable |
| `texture-filter-anisotropic-webgl` | anisotropic filtering |
| `texture-filter-linear-float32-webgl` | `linear` sampling of floating point textures |
| `texture-filter-linear-float16-webgl` | `linear` sampling of half-floating point textures |
## Compressed Textures
For more information on compressed textures, see e.g. [Compressed Textures in 2020](https://aras-p.info/blog/2020/12/08/Texture-Compression-in-2020/).
| Feature | Type | Devices | Description |
| --------------------------------- | ----------------------------------------- | -------------------------------- | ---------------------------------------- |
| `texture-compression-bc5-webgl` | DXT compressed textures (BC1-BC5) | Mainly desktops. | |
| `texture-compression-bc` | DXT compressed textures (BC1-BC7) | Mainly desktops. | Includes `texture-compression-bc5-webgl` |
| `texture-compression-etc` | Ericsson compression. | "Always" available (CPU decode). | Slow, not recommended |
| `texture-compression-astc` | Intel GPUs, Nividia Tegra, Mali ARM GPUs. | | |
| `texture-compression-pvrtc-webgl` | PowerVR chipsets. | iPhone, iPad, certain Android | |
| `texture-compression-atc-webgl` | Adreno GPUs | Qualcomm Snapdragon devices. | |
| `texture-compression-etc1-webgl` | Ericsson Compression | Older ETC compression. | |
## Supercompressed Textures
To use Basis supercompressed textures in luma.gl, see the [loaders.gl](https://loaders.gl) `BasisLoader` which can extract compressed textures from a basis encoded texture.
## WebGL notes
> Below is WebGL specific technical reference information that has been kept since luma.gl v8, it can be ignored for most applications
On WebGL devices, luma.gl maps WebGPU style texture format strings to WebGL constants under the hood.
It is however possible to provide overrides for the WebGL constants. The following tables provide some information about WebGL texture constants
If an application wants to store the texture at a certain resolution or in a certain format,
it can request the resolution and format with `internalFormat`.
WebGL will choose an internal representation with least the internal component sizes,
and exactly the component types shown for that format, although it may not match exactly.
### Internal Formats
| Sized Internal Format | Comp. | Size | Description |
| ------------------------------------ | ----- | -------- | --------------------------------------------------------------------------------------------- |
| `GL.R8` (WebGL 2) | 1 | 8 bits | red component |
| `GL.R16F` (WebGL 2) | 1 | 16 bits | half float red component |
| `GL.R32F` (WebGL 2) | 1 | 32 bits | float red component |
| `GL.R8UI` (WebGL 2) | 1 | 8 bits | unsigned int red component, `usampler`, no filtering |
| `GL.RG8` (WebGL 2) | 1 | 16 bits | red and green components |
| `GL.RG16F` (WebGL 2) | 2 | 32 bits | red and green components, half float |
| `GL.RG32F` (WebGL 2) | 2 | 64 bits | red and green components, float |
| `GL.RGUI` (WebGL 2) | 2 | 16 bits | red and green components, `usampler`, no filtering |
| `GL.RGB8` (WebGL 2) | 3 | 24 bits | red, green and blue components |
| `GL.SRGB8` (WebGL 2, EXT_sRGB) | 3 | 24 bits | Color values are encoded to/decoded from sRGB before being written to/read from framebuffer |
| `GL.RGB565` (WebGL 2) | 3 | 16 bits | 5 bit red, 6 bit green, 5 bit blue |
| `GL.R11F_G11F_B10F` (WebGL 2) | 3 | 32 bits | [11 and 10 bit floating point colors](https://www.opengl.org/wiki/Small_Float_Formats) |
| `GL.RGB9_E5` (WebGL 2) | 3 | 32 bits | [14 bit floating point RGB, shared exponent](https://www.opengl.org/wiki/Small_Float_Formats) |
| `GL.RGB16F` (WebGL 2) | 3 | 48 bits | half float RGB |
| `GL.RGB32F` (WebGL 2) | 3 | 96 bits | float RBG |
| `GL.RGB8UI` (WebGL 2) | 3 | 24 bits | unsigned integer 8 bit RGB: use `usampler`, no filtering |
| `GL.RGBA8` (WebGL 2) | 4 | 32 bits | 8 bit RGBA, typically what `GL.RGBA` "resolves" to |
| `GL.SRGB_APLHA8` (WebGL 2, EXT_sRGB) | 4 | 32 bits | Color values are encoded to/decoded from sRGB before being written to/read from framebuffer |
| `GL.RGB5_A1` (WebGL 2) | 4 | 16 bits | 5 bit RGB, 1 bit alpha |
| `GL.RGBA4444` (WebGL 2) | 4 | 16 bits | 4 bit RGBA |
| `GL.RGBA16F` (WebGL 2) | 4 | 64 bits | half float RGBA |
| `GL.RGBA32F` (WebGL 2) | 4 | 128 bits | float RGA |
| `GL.RGBA8UI` (WebGL 2) | 4 | 32 bits | unsigned integer 8 bit RGBA, `usampler`, no filtering |
### Texture Component Type
Describes the layout of each color component in memory.
| Value | WebGL 2 | WebGL 1 | Description |
| ----------------------------------- | ------- | ------------------------ | --------------------------------------------------- |
| `GL.UNSIGNED_BYTE` | Yes | Yes | GLbyte 8 bits per channel for `GL.RGBA` |
| `GL.UNSIGNED_SHORT_5_6_5` | Yes | Yes | 5 red bits, 6 green bits, 5 blue bits |
| `GL.UNSIGNED_SHORT_4_4_4_4` | Yes | Yes | 4 red bits, 4 green bits, 4 blue bits, 4 alpha bits |
| `GL.UNSIGNED_SHORT_5_5_5_1` | Yes | Yes | 5 red bits, 5 green bits, 5 blue bits, 1 alpha bit |
| `GL.BYTE` | Yes | No | |
| `GL.UNSIGNED_SHORT` | Yes | `WEBGL_depth_texture` | |
| `GL.SHORT` | Yes | No | |
| `GL.UNSIGNED_INT` | Yes | `WEBGL_depth_texture` | |
| `GL.INT` | Yes | No | |
| `GL.HALF_FLOAT` | Yes | `OES_texture_half_float` | |
| `GL.FLOAT` | Yes | `OES_texture_float` |
| `GL.UNSIGNED_INT_2_10_10_10_REV` | Yes | No | |
| `GL.UNSIGNED_INT_10F_11F_11F_REV` | Yes | No | |
| `GL.UNSIGNED_INT_5_9_9_9_REV` | Yes | No | |
| `GL.UNSIGNED_INT_24_8` | Yes | `WEBGL_depth_texture` | |
| `GL.FLOAT_32_UNSIGNED_INT_24_8_REV` | Yes | No | (pixels must be null) |
### Texture Format Combinations
This a simplified table illustrating what combinations of internal formats
work with what data formats and types. Note that luma.gl deduces `dataFormat` and `type` from `format` by taking the first value from the data format and data type entries in this table.
For more details, see tables in:
- [WebGL 2 spec](https://www.khronos.org/registry/webgl/specs/latest/2.0/)
- [OpenGL ES spec](https://www.khronos.org/opengles/sdk/docs/man3/html/glTexImage2D.xhtml)
| Internal Format | Data Format | Data Type |
| ------------------- | ----------------- | -------------------------------------------------------------------------- |
| `GL.RGB` | `GL.RGB` | `GL.UNSIGNED_BYTE` `GL.UNSIGNED_SHORT_5_6_5` |
| `GL.RGBA` | `GL.RGBA` | `GL.UNSIGNED_BYTE` `GL.UNSIGNED_SHORT_4_4_4_4` `GL.UNSIGNED_SHORT_5_5_5_1` |
| `GL.R8` | `GL.RED` | `GL.UNSIGNED_BYTE` |
| `GL.R16F` | `GL.RED` | `GL.HALF_FLOAT` `GL.FLOAT` |
| `GL.R32F` | `GL.RED` | `GL.FLOAT` |
| `GL.R8UI` | `GL.RED_INTEGER` | `GL.UNSIGNED_BYTE` |
| `GL.RG8` | `GL.RG` | `GL.UNSIGNED_BYTE` |
| `GL.RG16F` | `GL.RG` | `GL.HALF_FLOAT` `GL.FLOAT` |
| `GL.RG32F` | `GL.RG` | `GL.FLOAT` |
| `GL.RG8UI` | `GL.RG_INTEGER` | `GL.UNSIGNED_BYTE` |
| `GL.RGB8` | `GL.RGB` | `GL.UNSIGNED_BYTE` |
| `GL.SRGB8` | `GL.RGB` | `GL.UNSIGNED_BYTE` |
| `GL.RGB565` | `GL.RGB` | `GL.UNSIGNED_BYTE` `GL.UNSIGNED_SHORT_5_6_5` |
| `GL.R11F_G11F_B10F` | `GL.RGB` | `GL.UNSIGNED_INT_10F_11F_11F_REV` `GL.HALF_FLOAT` `GL.FLOAT` |
| `GL.RGB9_E5` | `GL.RGB` | `GL.HALF_FLOAT` `GL.FLOAT` |
| `GL.RGB16FG` | `GL.RGB` | `GL.HALF_FLOAT` `GL.FLOAT` |
| `GL.RGB32F` | `GL.RGB` | `GL.FLOAT` |
| `GL.RGB8UI` | `GL.RGB_INTEGER` | `GL.UNSIGNED_BYTE` |
| `GL.RGBA8` | `GL.RGBA` | `GL.UNSIGNED_BYTE` |
| `GL.SRGB8_ALPHA8` | `GL.RGBA` | `GL.UNSIGNED_BYTE` |
| `GL.RGB5_A1` | `GL.RGBA` | `GL.UNSIGNED_BYTE` `GL.UNSIGNED_SHORT_5_5_5_1` |
| `GL.RGBA4` | `GL.RGBA` | `GL.UNSIGNED_BYTE` `GL.UNSIGNED_SHORT_4_4_4_4` |
| `GL.RGBA16F` | `GL.RGBA` | `GL.HALF_FLOAT` `GL.FLOAT` |
| `GL.RGBA32F` | `GL.RGBA` | `GL.FLOAT` |
| `GL.RGBA8UI` | `GL.RGBA_INTEGER` | `GL.UNSIGNED_BYTE` |