Rendering ZBuffer to texture

Started by
5 comments, last by karwosts 13 years, 1 month ago
Hello I´m trying draw the zBuffer to texture in Directx 11,for do a Depth of field post process.

I have a render target Manager that setup one render target and the associated depthBuffer.

#include "StdAfx.h"
#include "RenderTargetMgr.h"
#include <d3d11.h>
#include "DX11Renderer.h"

/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
RenderTargetMgr::RenderTargetMgr()
{
m_pRenderTargetTexture = 0;
m_pRenderTargetView = 0;
m_pShaderResourceView = 0;

m_pDepthTexture = 0;
m_pDepthStencilView = 0;
m_pDepthResourceView = 0;

}

/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
RenderTargetMgr::~RenderTargetMgr()
{

}

/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
bool RenderTargetMgr::Init( ID3D11Texture2D* pRenderTargetTexture,bool bRenderTargetText, bool bDethText,int width, int height )
{

ID3D11Device* pDevice = DX11Renderer::GetInstance()->GetDevice();
D3D11_TEXTURE2D_DESC textureDesc;
HRESULT result;
D3D11_RENDER_TARGET_VIEW_DESC renderTargetViewDesc;
D3D11_SHADER_RESOURCE_VIEW_DESC shaderResourceViewDesc;

bool isExternBuffer = pRenderTargetTexture != NULL;
if( !isExternBuffer)
{
// Initialize the render target texture description.
ZeroMemory(&textureDesc, sizeof(textureDesc));

// Setup the render target texture description.
textureDesc.Width = width;
textureDesc.Height = height;
textureDesc.MipLevels = 1;
textureDesc.ArraySize = 1;
textureDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
textureDesc.SampleDesc.Count = 1;
textureDesc.Usage = D3D11_USAGE_DEFAULT;
textureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
textureDesc.CPUAccessFlags = 0;
textureDesc.MiscFlags = 0;

// Create the render target texture.
result = pDevice->CreateTexture2D(&textureDesc, NULL, &m_pRenderTargetTexture);
if(FAILED(result))
{
return false;
}
}
else
{
m_pRenderTargetTexture = pRenderTargetTexture;
}

// Setup the description of the render target view.
renderTargetViewDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
renderTargetViewDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
renderTargetViewDesc.Texture2D.MipSlice = 0;

// Create the render target view.
result = pDevice->CreateRenderTargetView(m_pRenderTargetTexture, isExternBuffer ? NULL : &renderTargetViewDesc, &m_pRenderTargetView);
if(FAILED(result))
{
return false;
}

// Setup the description of the shader resource view.
shaderResourceViewDesc.Format = DXGI_FORMAT_R32G32B32A32_FLOAT;
shaderResourceViewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
shaderResourceViewDesc.Texture2D.MostDetailedMip = 0;
shaderResourceViewDesc.Texture2D.MipLevels = 1;

if(bRenderTargetText)
{
// Create the shader resource view.
result = pDevice->CreateShaderResourceView(m_pRenderTargetTexture, &shaderResourceViewDesc, &m_pShaderResourceView);
if(FAILED(result))
{
return false;
}
}

//PARA DIBUJAR EL DEPTH TB A UNA TEXTURA


// Create depth stencil texture
D3D11_TEXTURE2D_DESC descDepth;
ZeroMemory( &descDepth, sizeof(descDepth) );
descDepth.Width = width;
descDepth.Height = height;
descDepth.MipLevels = 1;
descDepth.ArraySize = 1;
descDepth.Format = DXGI_FORMAT_R32_TYPELESS;
descDepth.SampleDesc.Count = 1;
descDepth.SampleDesc.Quality = 0;
descDepth.Usage = D3D11_USAGE_DEFAULT;

if(bDethText)
{
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL | D3D10_BIND_SHADER_RESOURCE;
}
else
{
descDepth.BindFlags = D3D10_BIND_DEPTH_STENCIL ;
}

descDepth.CPUAccessFlags = 0;
descDepth.MiscFlags = 0;
result = pDevice->CreateTexture2D( &descDepth, NULL, &m_pDepthTexture );
if( FAILED( result ) )
{
return false;
}

//if(!bDethText)
{
// Create the depth stencil view
D3D11_DEPTH_STENCIL_VIEW_DESC descDSV;
ZeroMemory( &descDSV, sizeof(descDSV) );
descDSV.Format = DXGI_FORMAT_D32_FLOAT;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
result = pDevice->CreateDepthStencilView( m_pDepthTexture, &descDSV, &m_pDepthStencilView );
if( FAILED( result ) )
{
return false;
}
}

if(bDethText)
{
D3D11_SHADER_RESOURCE_VIEW_DESC viewDesc;
viewDesc.Format = DXGI_FORMAT_R32_FLOAT;
viewDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
viewDesc.Texture2D.MostDetailedMip = 0;
viewDesc.Texture2D.MipLevels = 1;
result = pDevice->CreateShaderResourceView( m_pDepthTexture, &viewDesc, &m_pDepthResourceView);
if( FAILED( result ) )
{
return false;
}
}

return true;
}

/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
void RenderTargetMgr::End()
{

if(m_pDepthResourceView)
{
m_pDepthResourceView->Release();
m_pDepthResourceView = 0;
}

if(m_pDepthStencilView)
{
m_pDepthStencilView->Release();
m_pDepthStencilView = 0;
}

if(m_pDepthTexture)
{
m_pDepthTexture->Release();
m_pDepthTexture = 0;
}

if(m_pShaderResourceView)
{
m_pShaderResourceView->Release();
m_pShaderResourceView = 0;
}

if(m_pRenderTargetView)
{
m_pRenderTargetView->Release();
m_pRenderTargetView = 0;
}

if(m_pRenderTargetTexture)
{
m_pRenderTargetTexture->Release();
m_pRenderTargetTexture = 0;
}

return;

}

/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
void RenderTargetMgr::ActiveRenderTarget( )
{
ID3D11DeviceContext* pDeviceC = DX11Renderer::GetInstance()->GetDeviceContext();

// Bind the render target view and depth stencil buffer to the output render pipeline.
pDeviceC->OMSetRenderTargets(1, &m_pRenderTargetView, m_pDepthStencilView);


}

/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
void RenderTargetMgr::ClearRenderTarget(ColorF color)
{
float acolor[4];

ID3D11DeviceContext* pDeviceC = DX11Renderer::GetInstance()->GetDeviceContext();


// Setup the color to clear the buffer to.
acolor[0] = color.GetR();
acolor[1] = color.GetG();
acolor[2] = color.GetB();
acolor[3] = color.GetA();

// Clear the back buffer.
pDeviceC->ClearRenderTargetView(m_pRenderTargetView, acolor);

// Clear the depth buffer.
pDeviceC->ClearDepthStencilView(m_pDepthStencilView, D3D11_CLEAR_DEPTH, 1.0f, 0);

}

/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
ID3D11ShaderResourceView* RenderTargetMgr::GetRenderTargetTexture()
{
return m_pShaderResourceView;
}


/***********************************************************************************************************/
/*
/***********************************************************************************************************/
//
ID3D11ShaderResourceView* RenderTargetMgr::GetDepthTexture()
{
return m_pDepthResourceView;
}



Then I have created two Render Target.One is the normal render,and another is only for draw in a texture the zBuffer.Also I Have the next Depth states:



bool DX11Renderer::InitZStates()
{
HRESULT bInit = S_OK;
D3D11_DEPTH_STENCIL_DESC depthStencilDesc;

// Initialize the description of the stencil state.
ZeroMemory(&depthStencilDesc, sizeof(depthStencilDesc));

// Set up the description of the stencil state.
depthStencilDesc.DepthEnable = true;
depthStencilDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;


depthStencilDesc.StencilEnable = true;
depthStencilDesc.StencilReadMask = D3D11_DEFAULT_STENCIL_READ_MASK;
depthStencilDesc.StencilWriteMask = D3D11_DEFAULT_STENCIL_WRITE_MASK;

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

// Stencil operations if pixel is back-facing.
depthStencilDesc.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_DECR;
depthStencilDesc.BackFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
depthStencilDesc.BackFace.StencilFunc = D3D11_COMPARISON_ALWAYS;

// Create the depth stencil state.
bInit = m_pDXDevice->CreateDepthStencilState(&depthStencilDesc, &m_ZState[BF_ENABLE]);
if( FAILED( bInit ) )
{
return false;
}
depthStencilDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL;
// Create the depth stencil state.
bInit = m_pDXDevice->CreateDepthStencilState(&depthStencilDesc, &m_ZState[BF_LESSOREQUAL]);
if( FAILED( bInit ) )
{
return false;
}


depthStencilDesc.DepthEnable = false;
bInit = m_pDXDevice->CreateDepthStencilState(&depthStencilDesc, &m_ZState[BF_DISABLE]);
if( FAILED( bInit ) )
{
return false;
}

m_pDXDeviceC->OMSetDepthStencilState(m_ZState[BF_ENABLE],1);
return true;
}



And apply the code:



//I have painted the scene to get the depth buffer texture in normal render target
m_pRenderTargets[PPRT_NORMAL]->ActiveRenderTarget();
m_pRenderTargets[PPRT_NORMAL]->ClearRenderTarget(fColor);
m_pDXDeviceC->OMSetDepthStencilState(m_ZState[BF_ENABLE],1);

RenderScene();

//I draw the resultant texture in screen
m_pRenderTargets[PPRT_FINAL]->ActiveRenderTarget();
m_pRenderTargets[PPRT_FINAL]->ClearRenderTarget(fColor);

m_pScreen->SetTexture(m_pRenderTargets[PPRT_NORMAL]->GetDepthTexture());
m_pScreen->Draw();

m_pSwapChain->Present(0, 0);



I have putted the m_ZState[BF_ENABLE],but my depth texture is fully red.Can SomeOne Help me???
Advertisement
Also I have been trying paint the zbuffer with this shader code:



//--------------------------------------------------------------------------------------
// File: DethShader.fx
//
// jviruss
//--------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------
// Buffer para las transformadas
//--------------------------------------------------------------------------------------
cbuffer TransformsBuffer : register( b0 )
{
matrix m_World;
matrix m_View;
matrix m_Proyection;

}


//--------------------------------------------------------------------------------------
// Estructura para la entrada del VerTex Buffer
//--------------------------------------------------------------------------------------
struct VS_INPUT
{
float4 position : POSITION;
float3 normal : NORMAL;
float2 textcoord : TEXCOORD;

};

//--------------------------------------------------------------------------------------
// Estructura para la entrada del PiXel Buffer
//--------------------------------------------------------------------------------------

struct OUT_DEPTH
{
float4 Position : POSITION;
float Distance : TEXCOORD0;
};



//--------------------------------------------------------------------------------------
// Vertex Shader
//--------------------------------------------------------------------------------------
OUT_DEPTH VS( VS_INPUT input )
{
OUT_DEPTH Out;

float4 position = mul( input.position, m_World );
position = mul( position, m_View );
position = mul( position, m_Proyection);


Out.Position = position;

float value = length(position - m_WorldCameraPos);
Out.Distance.x = (Out.Position.z/Out.Position.w);

return Out;

}


//--------------------------------------------------------------------------------------
// Pixel Shader
//--------------------------------------------------------------------------------------
float4 PS( OUT_DEPTH input) : SV_Target
{
return float4(input.Distance.x,0,0,1);
}




The meshes are all red is as if the "value" variable never had a different value.Is something wrong in the zBuffer configuration?


float value = length(position - m_WorldCameraPos);



This value is never used in your vertex shader, is this on purpose?

Have you tried to render your scene without rendering to the texture, if so, are you able to see your geometry then?

Have you tried to render this in PIX and investigate the current results in there?
Sounds like it could be just an issue with the nonlinearity of the depth buffer. In a typical 1/1000 near/far depth buffer I'd guess that probably 99% of the pixels would have a value between 0.95 and 1, which might not be noticeable as a color.

What kind of projection are you using, and how close are the objects to you that you are trying to draw? It might be a good idea to try to linearise the depth if you want to visualize it as a texture.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
[color="#284b72"]karwosts Thanks I had the near in 0.1f and the far in 100000 units.I had putted 1 and 100 and it works fine.Why???Dou you can explain me it better?I want understand all.
Cheers!!!
Karwosts How I linearize the zBuffer???
Don't have time to write a tutorial now, but you can read here for info, particularly the mathematics section:

http://en.wikipedia.org/wiki/Z-buffering
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game

This topic is closed to new replies.

Advertisement