HLSL Shader + Depth Map Problem

Started by
1 comment, last by neroziros 9 years, 8 months ago

Hi there! I write here because I'm having a problem rendering the scene depth as a texture.

I have been following this tutorial but the depth is rendered as a black texture. Any help will be greatly appreciated. Here is what I have been doing so far:

DEPTH MAP CREATION


// CREATE THE AUXILIARY DEPTH MAP
D3D11_TEXTURE2D_DESC texDesc;
ZeroMemory(&texDesc, sizeof(texDesc));
texDesc.Width = screenWidth;
texDesc.Height = screenHeight;
texDesc.MipLevels = 1;
texDesc.ArraySize = 1;
texDesc.Format = DXGI_FORMAT_R32_TYPELESS;
texDesc.SampleDesc.Count = 1;
texDesc.SampleDesc.Quality = 0;
texDesc.Usage = D3D11_USAGE_DEFAULT;
texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_DEPTH_STENCIL ;
texDesc.CPUAccessFlags = 0;
texDesc.MiscFlags = 0;
result = m_device->CreateTexture2D(&texDesc, 0, &m_depthMap);
if (FAILED(result))return false;


// Create the depth stencil view.
D3D11_DEPTH_STENCIL_VIEW_DESC dsvd;
ZeroMemory(&dsvd, sizeof(dsvd));
dsvd.Format = DXGI_FORMAT_D32_FLOAT;
dsvd.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsvd.Texture2D.MipSlice = 0;
result = m_device->CreateDepthStencilView(m_depthMap, &dsvd, &m_depthMapView);
if (FAILED(result))return false;


// Create the shader resource view (this is what will be sent to the shader)
D3D11_SHADER_RESOURCE_VIEW_DESC srvd;
srvd.Format = DXGI_FORMAT_R32_FLOAT;
srvd.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvd.Texture2D.MipLevels = texDesc.MipLevels;
srvd.Texture2D.MostDetailedMip = 0;
result = m_device->CreateShaderResourceView(m_depthMap, &srvd, &m_depthShaderResource);
if (FAILED(result))return false;

_

CREATE THE DEPTH STENCIL STATE TO BE USED DURING NORMAL RENDERING


// Create the new depthstate description and depth state
D3D11_DEPTH_STENCIL_DESC dsDesc;
ZeroMemory(&dsDesc, sizeof(D3D11_DEPTH_STENCIL_DESC));
dsDesc.DepthEnable = true;
dsDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
dsDesc.DepthFunc = D3D11_COMPARISON_LESS;
dsDesc.StencilEnable = false;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0x00;


// Stencil operations if pixel is front-facing
dsDesc.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR;
dsDesc.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS;


// Stencil operations if pixel is back-facing
dsDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
dsDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;
// Create depth stencil state
device->CreateDepthStencilState(&dsDesc, &DepthState);

_

DEPTH MAP RENDER


// Setup the color to clear the buffer to.
color[0] = red;
color[1] = green;
color[2] = blue;
color[3] = alpha;

// Clear the back buffer.
m_deviceContext->ClearRenderTargetView(m_renderTargetView, color);
    
// Clear the depth buffer.
m_deviceContext->ClearDepthStencilView(m_depthMapView, D3D11_CLEAR_DEPTH, 1.0f, 0);

// Set the render targets
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, m_depthMapView);
// Render the scene normally (Here I don't do anything depth buffer related exept binding the depthstencil state previously created)
// ...
deviceContext->OMSetDepthStencilState(DepthState, 1);
// ....

_

I "TRY" TO RENDER THE DEPTH MAP


// I set the current bound depth map as null because I read that you can't sample a depth map srv while it is still being used (Even if you don't write to it)
m_deviceContext->OMSetRenderTargets(1, &m_renderTargetView, NULL);

// Setup the render parameters (nothing depth related)
//  ...
// Set depth stencil state
m_D3D->GetDeviceContext()->OMSetDepthStencilState(pDepthState, 0);

// Send the depth map to the shader
m_D3D->GetDeviceContext()->PSSetShaderResources(1, 1,&m_depthShaderResource);
m_D3D->GetDeviceContext()->PSSetShaderResources(2, 1, &g_pColorTextureRV);

// Render the quad 
// ...

// Clean SRVs
m_D3D->GetDeviceContext()->VSSetShaderResources(0, 1, &nullSRV);
m_D3D->GetDeviceContext()->PSSetShaderResources(0, 1, &nullSRV);
m_D3D->GetDeviceContext()->PSSetShaderResources(1, 1, &nullSRV);

// Show the frame
m_swapChain->Present(0, 0);

_

AND HERE IS HOW I SAMPLE IT INSIDE THE SHADER


StructuredBuffer<Particle> SimulationState : register(t0);
Texture2D DepthMap : register(t1);
Texture2D ColorMap : register(t2);


SamplerState samplerPoint
{
Filter = MIN_MAG_MIP_POINT;
AddressU = Clamp;
AddressV = Clamp;
};


float4 PSMAIN(in PS_INPUT input) : SV_Target
{
float DepthMapSample = DepthMap.Sample(samplerPoint, input.texcoords).r;
float4 color = input.color * DepthMapSample;


return(color);
}

I added a temporal ColorMap texture to check if the texcoords and sampling was working and , as expected, they do are working fine. The problem is with the depth map which is rendered fully black.

Anyone has an idea about what could be the problem here? If I can't solve this I guess that I will have to go for the MRTs route (writing the depth maps manually to an extra render target). But I really want to use the DX11 depth maps to aovid the extra calculations.

Cheers and thanks for your time!

Advertisement

Have you enabled debugging when creating the D3D objects?

Playing with the depth buffers and stuff may not be always obvious - the debugging information may give you some insight where the problem is. Also, you could use some 3rd party software to inspect the depth buffer content after rendering. That might help you to locate the problem part of the code.

Note : Actually it is possible to perform depth testing and read the depth buffer at the same time IF the depth stencil view is read_only.

Cheers!

Thanks! I will try using Nsight this week and post results.

In the meatime I have implemented a MRT version and it worked perfectly. Cheers!

This topic is closed to new replies.

Advertisement