Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm trying to read the values in a depth texture of type DXGI_FORMAT_D24_UNORM_S8_UINT.

I know this means "24 bits for depth, 8 bits for stencil" "A 32-bit z-buffer format that supports 24 bits for depth and 8 bits for stencil.", but how do you interpret those 24 bits?

It's clearly not going to be a 32-bit int, and it's not going to be a 32-bit float. If it is an integer value, how "far away" is a value of "1" in the depth texture?

share|improve this question

4 Answers 4

up vote 0 down vote accepted

It's an Unsigned NORMalized float, which is a floating-point value between 0.0 and 1.0.

EDIT: To clarify, the Depth component is accessed as a float, and the Stencil component is accessed as an unsigned integer.

share|improve this answer
    
_UINT indicates that it's quite clearly not a float. –  Darth Satan Jul 2 '12 at 1:49
    
@mh01 Actually the D24 part is UNORM, and he's right –  bobobobo Jul 2 '12 at 2:15
    
Check the DX SDK - 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]" - from the shader perspective he's right, from the resource perspective he's totally wrong. –  Darth Satan Jul 2 '12 at 2:31
    
No, look carefully. I believe UNORM refers to a float datatype. –  bobobobo Jul 2 '12 at 2:33
1  
Sorry but that's a direct quote from the DX SDK page for DXGI_FORMAT - msdn.microsoft.com/en-us/library/windows/desktop/… - look at "Format Modifiers" towards the bottom. The data type is explicitly specified as unsigned integer by the documentation but it is interpreted as float in your shader - read it on the CPU and you'll get 24-bit uints, not 24-bit floats. –  Darth Satan Jul 2 '12 at 13:48

Here is some demo code which shows how it works:

// create a temporary texture 
D3D11_TEXTURE2D_DESC desc; 
depthStencilTexture->GetDesc(&desc); 
desc.Usage = D3D11_USAGE_STAGING; 
desc.BindFlags = 0; 
desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; 
desc.MiscFlags = 0; 

ID3D11Texture2D* tmpTexture = nullptr; 
HRESULT hr = getDevice()->CreateTexture2D(&desc, nullptr, &tmpTexture); 

// Copy depth buffer
getImmediateContextD3D()->CopyResource(tmpTexture, depthStencilTexture); 

// access depth buffer
D3D11_MAPPED_SUBRESOURCE mappedRes; 
getImmediateContextD3D()->Map(tmpTexture, 0, D3D11_MAP_READ, 0, &mappedRes); 

unsigned int* color = (unsigned int*)mappedRes.pData;

// Extract 24 depth bits
float depth = static_cast<float>(color & 0x00FFFFFF); 
depth /= 16777216f; // divide bei 2^24

// compute a grayscale value [0;255]
unsigned char colorValue = static_cast<unsigned char>(depth * 255.0f);
share|improve this answer

I solved this problem by using DXGI_FORMAT_D32_FLOAT in my depth texture instead. It turned out that the z-buffer is all floats between 0.0f and 1.0f.

share|improve this answer

Generally for your texture (or rather the SRV you'll create) you use a format in the same "type" family, in this case DXGI_FORMAT_R24G8_TYPELESS - then when you sample it in your shader you just use a .r swizzle to get the depth value out (in 0..1 range). You should not, of course, be reading it back to the CPU - how to interpret the data is going to be the least of your problems if you do.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.