[DirectX 10] Render target formats

Started by
1 comment, last by Aqua Costa 13 years, 4 months ago
Since I started using DirectX Ive mostly used the DXGI_FORMAT_R8G8B8A8_UNORM format in my render targets.
Ive also used DXGI_FORMAT_R32_FLOAT format to store linear depth with more precision.

But I dont understand how the formats work...

1-Whats the difference between for example DXGI_FORMAT_R8G8B8A8_UNORM and DXGI_FORMAT_R32G32B32A32_UINT?

2-What improves the precision? DXGI_FORMAT_R32_FLOAT or DXGI_FORMAT_R32_UINT? and why?

I know that R32 means a channel with 32 bits. If the format is R32G32B32A32 is has 4 channels with 32 bits, but I dont know what do the 32 bits are...

Usually the render targets I use go from 0 to 1, does other render targets support higher values?

Thanks in advance
Advertisement
The full listing of the format suffixes and what they mean are here. But I'll try to give you a brief overview...

So like you already said, the numbers in the format indicate the number of bits used for storing each component. So R8G8B8A8 means 8 bits per component for 32 bits total, R16G16B16A16 means 16 per component, and so on. But on its own, that doesn't tell you how values are stored in that format or how they're interpreted when you sample that format as a texture. That's where the suffix comes in. The suffix will indicate whether the values are stored as floating point or integer, and it will indicate how the values are interpreted when you sample them. They suffixes are as follows:

1. UNORM: this stands for "unsigned normalized integer". "Normalized" means that the value is converted from an integer to a floating point number. Since it's unsigned, the range of that floating point number is [0.0, 1.0]. The integer is mapped so that it's minimum value (0) corresponds to zero, and it's maximum value maps to to 1.0. So for an 8-bit integer the max is 255, so 255 represents 1.0 and 127 represents 0.5 and so on.

2. SNORM: this stands for "signed normalized integer". This is very similar to UNORM, except you have a sign bit. So the integer is mapped to [-1.0, 1.0] instead of [0.0, 1.0]. Normal integer sign bit rules are used for storage and conversion.

3. UINT: this stands for "unsigned integer". In this format values are stored as unsigned integers, just like in UNORM. The difference is that when you sample this format, it's not normalized to the [0, 1] range. Instead you sample the actual underlying integer value stored in the texture.

4. SINT: same as UINT, except with a sign bit so that you can have negative values.

5. FLOAT: values are stored as floating point, and interpreted as floating point.

6. SRGB: same as UNORM, except that values are converted from linear to sRGB color space when written (and the opposite conversion takes place when sampling the texture).

As for FLOAT vs. UINT, it depends what you want to store in that texture. If you only want to store integer values, then obviously UINT is a much better choice since a FLOAT will waste a lot of precision. If you need floating point values, then you usually want FLOAT. By the same token if you only want to store [0,1] values, then a UNORM format will have better precision than a FLOAT format with the same number of bits.
Thanks a lot. It was very helpfull.

This topic is closed to new replies.

Advertisement