Skip to content

Image Format

Color attachments such as colortex and shadowcolor buffers, as well as custom images and textures, store values in different formats with varying bit depth and layout.

The default format for color attachments is RGBA (which equates to RGBA8 on most systems). However, a shader pack can specify the format using the <bufferName>Format directive.

The available image formats and their meanings are described below.

Normalized

Normalized buffers store “floating point” values in a fixed range. The values are stored as integers internally, which are converted to/from floating point numbers during read/write. Any values outside the range are clamped to fit in the range.

Detailed explanation: OpenGL Wiki - Normalized Integer

Unsigned Normalized Formats

Unsigned normalized buffers support values from 0.0 to 1.0 (inclusive).

Image FormatBit DepthPixel FormatPixel TypeImageRequirements
RGBA164×16RGBAUNSIGNED_SHORT✔️
RGBA84×8RGBAUNSIGNED_BYTE✔️
RGB10_A210/10/10/2RGBAUNSIGNED_INT_2_10_10_10_REV✔️
RGBA4*4×4RGBAUNSIGNED_SHORT_4_4_4_4_REVOpenGL 4.2+
GL_RGB5_A15/5/5/1RGBAUNSIGNED_SHORT_1_5_5_5_REVOpenGL 4.2+
RGB163×16RGBUNSIGNED_SHORT
RGB83×8RGBUNSIGNED_BYTE
RGB565*5/6/5RGBUNSIGNED_SHORT_5_6_5_REVOpenGL 4.1+ or ARB_ES2_compatibility
RG162×16RGUNSIGNED_SHORT✔️
RG82×8RGUNSIGNED_BYTE✔️
R1616REDUNSIGNED_SHORT✔️
R88REDUNSIGNED_BYTE✔️
RGBA2*4×2RGBA
R3_G3_B23/3/2REDUNSIGNED_BYTE_2_3_3_REV

*Requires Iris 1.8+

Signed Normalized Formats

Signed normalized buffers support values from -1.0 to 1.0 (inclusive).

Image FormatBit DepthPixel FormatPixel TypeImage
RGBA16_SNORM4×16RGBASHORT✔️
RGBA8_SNORM4×8RGBABYTE✔️
RGB16_SNORM3×16RGBSHORT
RGB8_SNORM3×8RGBBYTE
RG16_SNORM2×16RGSHORT✔️
RG8_SNORM2×8RGBYTE✔️
R16_SNORM16REDSHORT✔️
R8_SNORM8REDBYTE✔️

Floating Point

Floating point buffers allow the attachment to store true floating point values. They are only available with larger than default precision due to the increased storage needed for floating point values. However, they offer a significantly larger range of values, allowing the storing of HDR values.

Detailed explanation: OpenGL Wiki - Small Float Formats

Floating Point Formats

Image FormatBit DepthPixel FormatPixel TypeImage
RGBA32F4×32RGBAFLOAT✔️
RGBA16F4×16RGBAHALF_FLOAT✔️
RGB32F3×32RGBFLOAT
RGB16F3×16RGBHALF_FLOAT
R11F_G11F_B10F11/11/10RGBUNSIGNED_INT_10F_11F_11F_REV*✔️
RGB9_E5SpecialRGB5_9_9_9_REV*
RG32F2×32RGFLOAT✔️
RG16F2×16RGHALF_FLOAT✔️
R32F32REDFLOAT✔️
R16F16REDHALF_FLOAT✔️

*Requires Iris 1.8+

The RGB9_E5 format uses a 5-bit exponent for all three terms (R, G, and B), where each component has a 9 bit mantissa. This allows for significantly more precision than R11F_G11F_B10F, which only has 6 to 5 bits of precision per component. However, R11F_G11F_B10F has individual exponents for each component.

Integral

Bit DepthSigned MinSigned MaxUnsigned Max
32-214748364821474836474294967295
10-5125111023
16-327683276765535
8-128127255
2-213

Unsigned Integral Formats

Unsigned integral buffers store unsigned integers, which will not be interpreted as negative values (although they can be cast to signed integers after being read). As such they do not directly allow the storage of negative integers, but have double the range of their signed cousins in the positive domain.

Image FormatBit DepthPixel FormatPixel TypeImage
RGBA32UI4×32RGBA_INTEGERUNSIGNED_INT✔️
RGBA16UI4×16RGBA_INTEGERUNSIGNED_SHORT✔️
RGBA8UI4×8RGBA_INTEGERUNSIGNED_BYTE✔️
RGB10_A2UI*10/10/10/2RGBA_INTEGERUNSIGNED_INT_2_10_10_10_REV✔️
RGB32UI3×32RGB_INTEGERUNSIGNED_INT
RGB16UI3×16RGB_INTEGERUNSIGNED_SHORT
RGB8UI3×8RGB_INTEGERUNSIGNED_BYTE
RG32UI2×32RG_INTEGERUNSIGNED_INT✔️
RG16UI2×16RG_INTEGERUNSIGNED_SHORT✔️
RG8UI2×8RG_INTEGERUNSIGNED_BYTE✔️
R32UI32RED_INTEGERUNSIGNED_INT✔️
R16UI16RED_INTEGERUNSIGNED_SHORT✔️
R8UI8RED_INTEGERUNSIGNED_BYTE✔️

*Requires Iris 1.8+

Signed Integral Formats

Signed integral buffers store signed integers, just like the tin says. These are standard two’s complement integers, which means they can store negative values.

Image FormatBit DepthPixel FormatPixel TypeImage
RGBA32I4×32RGBA_INTEGERINT✔️
RGBA16I4×16RGBA_INTEGERSHORT✔️
RGBA8I4×8RGBA_INTEGERBYTE✔️
RGB32I3×32RGB_INTEGERINT
RGB16I3×16RGB_INTEGERSHORT
RGB8I3×8RGB_INTEGERBYTE
RG32I2×32RG_INTEGERINT✔️
RG16I2×16RG_INTEGERSHORT✔️
RG8I2×8RG_INTEGERBYTE✔️
R32I32RED_INTEGERINT✔️
R16I16RED_INTEGERSHORT✔️
R8I8RED_INTEGERBYTE✔️

Additional Pixel Types

The shader loader supports some additional pixel types, not directly associated with specific image formats, that can be used when loading raw custom textures. See the OpenGL Wiki for more information about these.

Pixel Type
UNSIGNED_BYTE_3_3_2
UNSIGNED_SHORT_5_6_5
UNSIGNED_SHORT_4_4_4_4
UNSIGNED_SHORT_5_5_5_1
UNSIGNED_INT_8_8_8_8
UNSIGNED_INT_8_8_8_8_REV
UNSIGNED_INT_10_10_10_2

Further Reading