5
\$\begingroup\$

I'm studying DX12. I came across this texture format:

DXGI_FORMAT_R8G8B8A8_UNORM
A four-component, 32-bit unsigned-normalized-integer format that supports 8 bits per channel including alpha.

It's not clear to me exactly - what values does each RGBA element store? As it is clear from the description above, these values are from 0 to 1 i.e. UNORM. But how, for example, can 1 byte R8 store a real number from 0.0f to 1.0f?

\$\endgroup\$

1 Answer 1

9
\$\begingroup\$

The format modifiers like _UNORM / _SNORM / _FLOAT, etc... are documented on the DXGI_FORMAT Page:

Format Modifiers

Each enumeration value contains a format modifier which describes the data type.

_UNORM
Unsigned normalized integer; which is interpreted in a resource as an unsigned integer, and is interpreted in a shader as an unsigned normalized floating-point value in the range [0, 1]. All 0's maps to 0.0f, and all 1's maps to 1.0f. A sequence of evenly spaced floating-point values from 0.0f to 1.0f are represented. For instance, a 2-bit UNORM represents 0.0f, 1/3, 2/3, and 1.0f.

In your example format DXGI_FORMAT_R8G8B8A8_UNORM there are 8 bits per channel, so 28 = 256 possible values (0-255).

Those will map to float values in the range 0-1 like the given example in the documentation:

Int Value Float Value 0 0 / 255 = 0.0f 1 1 / 255 ≈ 0.00392156862f 2 2 / 255 ≈ 0.00784313725f 3 3 / 255 ≈ 0.01176470588f ... ... 127 127 / 255 ≈ 0.49803921568f 128 128 / 255 ≈ 0.50196078431f ... ... 253 253 / 255 ≈ 0.99215686274f 254 254 / 255 ≈ 0.99607843137f 255 255 / 255 = 1.0f 
\$\endgroup\$
6
  • 1
    \$\begingroup\$ Thank you very much! As I understand it, this means that the texture itself stores R value from 0 to 255, G from 0 to 255, B from 0 to 255, A from 0 to 255, but these values in the shader are converted to R from 0 to 1, G from 0 to 1, B from 0 to 1, and A from 0 to 1. Did I understand correctly? \$\endgroup\$ Commented Apr 19, 2023 at 16:21
  • 4
    \$\begingroup\$ @black4 correct. The data is stored as an unsigned integer between 0-255 per channel. When sampled from a shader the resulting value per channel will be between 0.0f - 1.0f (as given by the mapping table above) \$\endgroup\$ Commented Apr 19, 2023 at 16:35
  • 1
    \$\begingroup\$ OK, thank you. I want to test my assumptions. For example, there is a format: DXGI_FORMAT_R8G8B8A8_UINT In the texture R has from 0 to 255, G has from 0 to 255, B has from 0 to 255, and A has from 0 to 255. And in the shader, R has from 0 to 255, G has from 0 to 255, B has from 0 to 255, A has from 0 to 255. Right? \$\endgroup\$ Commented Apr 19, 2023 at 16:48
  • 4
    \$\begingroup\$ @black4 correct :) And DXGI_FORMAT_R16G16B16A16_UINT for example can have a value from 0-65535 per channel, etc... \$\endgroup\$ Commented Apr 19, 2023 at 17:07
  • 1
    \$\begingroup\$ See DirectXTex for examples for all formats. \$\endgroup\$ Commented Apr 24, 2023 at 7:52

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.