DirectX 11 depth buffer problem

Started by
3 comments, last by iedoc 12 years, 7 months ago
hi im kinda new to these forums so not sure if this is the correct board for posting this, but i have a problem with my depth buffer not working (properly)...

i have set it up like this (following the code from http://www.rastertek.../dx11tut03.html):


// Initialize the description of the depth buffer.
D3D11_TEXTURE2D_DESC dbDesc;
ZeroMemory(&dbDesc, sizeof(dbDesc));

// Set up the description of the depth buffer.
dbDesc.Width = SCREEN_WIDTH;
dbDesc.Height = SCREEN_HEIGHT;
dbDesc.MipLevels = 1;
dbDesc.ArraySize = 1;
dbDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
dbDesc.SampleDesc.Count = 1;
dbDesc.SampleDesc.Quality = 0;
dbDesc.Usage = D3D11_USAGE_DEFAULT;
dbDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
dbDesc.CPUAccessFlags = 0;
dbDesc.MiscFlags = 0;

// Create the texture for the depth buffer using the filled out description.
hr = m_mainPtrs.m_pDev->CreateTexture2D(&dbDesc, NULL, &m_depthStencilBuffer);
if (FAILED(hr)) {SHOWERRORMSG("Creating depth stencil buffer target failed"); return FALSE;}

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

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

dsDesc.StencilEnable = false;
dsDesc.StencilReadMask = 0xFF;
dsDesc.StencilWriteMask = 0xFF;

// 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 the depth stencil state.
hr = m_mainPtrs.m_pDev->CreateDepthStencilState(&dsDesc, &m_depthStencilState);
if (FAILED(hr)) {SHOWERRORMSG("Creating depth stencil state description failed"); return FALSE;}

// Set the depth stencil state.
m_mainPtrs.m_pDevCon->OMSetDepthStencilState(m_depthStencilState, 1);

// Initailze the depth stencil view.
D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc;
ZeroMemory(&dsvDesc, sizeof(dsvDesc));

// Set up the depth stencil view description.
dsvDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
dsvDesc.Texture2D.MipSlice = 0;

// Create the depth stencil view.
hr = m_mainPtrs.m_pDev->CreateDepthStencilView(m_depthStencilBuffer, &dsvDesc, &m_mainPtrs.m_depthStencilView);
if (FAILED(hr)) {SHOWERRORMSG("Creating depth stencil view description failed"); return FALSE;}

// Bind the render target view and depth stencil buffer to the output render pipeline.
m_mainPtrs.m_pDevCon->OMSetRenderTargets(1, &m_mainPtrs.m_pBackbuffer, m_mainPtrs.m_depthStencilView);

of course i clear the depth buffer with

mptrs.m_pDevCon->ClearDepthStencilView(mptrs.m_depthStencilView, D3D11_CLEAR_DEPTH|D3D11_CLEAR_STENCIL, 1.0f, 0);


now strange enough, depth testing isnt working... the code compiles correctly, i also checked if the used DXGI_FORMAT_D24_UNORM_S8_UINT format is supported for D3D11_FORMAT_SUPPORT_DEPTH_STENCIL, and it is. Further i tried clearing only the depth stencil, turning stencil test off and various depth functions.

the different depth functions also dont give results as expected;
i draw two intersecting objects, always one of them is completely obscuring the other, dependent on the depth comparison function (1 means obscures 2, - means nothing is drawn , obj1 is sent to the pipeline first):
depth buffer cleared to 1.0f:

LESS LEQ ALWAYS NEVER GRTR GREQ EQ
Obj1 1 2 2 _ _ _ _
Obj2 2 1 1


depth buffer cleared to 0.0f:

LESS LEQ ALWAYS NEVER GRTR GREQ EQ
Obj1 1 2 2 _ _ _ 2
Obj2 2 1 1 1


EDIT: hm seems that monospace copy & paste didnt quite pan out on those tables^^, but well you get what is should be where i think

it looks like the whole geometry is collapsed to the near clipping plane. can it be that a projection matrix collapses geometry to the near clipping plane (i use D3DPerspectivesomething to calculate my projection matrix)? never thought about that... and if so why does the LESS depth func act different? obj1 is still getting sent to pipeline first, so it should be below obj2, but its not.

also, obj1 should be partly behind obj2 (since their geometry intersects) however always one is completely drawn above the other....

ive been sitting at this for hours! pls help!!!

thx in advance

system: Windows7 (obviously with dx11)
compiler: VS 10 express
DX SDK Version: ummmm... i downloaded the latest one last week

btw: excuse my bad english, if anything is unclear, or you need more info, just ask

EDIT: update: by passing the vertex shaders output position to the pixel shader i tried drawing the actual depth values in color. the pixelshader now just returns

float4((depthvalue-0.9)*10.0f,0,0,1)

, where depthvalue is position.z/position.w. the subtraction by 0.9 and multiplication by 10 is just so the range 0.9 to 1 gets a better resolution.
i can see clearly that my depth values are calculated correctly, they simply aren't written to the depthbuffer properly :///



cbuffer pfConst
{
matrix matView;
matrix matProj;
}

cbuffer poConst
{
matrix matWorld;
}

struct VIn
{
float4 position : Position;
float3 normal : Normal;
float2 tex : TexCoord0;
float4 tangent : Tangent0;
};

struct PIn
{
float4 position : SV_POSITION;
float2 tex : TEXCOORD0;
float3 lightDirSurf : TEXCOORD1;
float4 lightParam : TEXCOORD2;
};

sampler texSamp;
Texture2D <float4> colorTex;

PIn VShader(VIn input)
{
PIn output;
input.position.w = 1.0f;
float4 worldPos = mul(input.position,matWorld);
float4 viewPos = mul(worldPos,matView);
output.position = mul(viewPos,matProj);
output.tex = input.tex; //ignore this
output.lightDirSurf = float4(0.0,0.0,0.0,0.0); //ignore this
output.lightParam = output.position; //ignore this
// output.lightParam = float4(lightDist, LightPos.w, 0.0f, 0.0f); //used this texccord for debugging depth
return output;
}


float4 PShader(PIn input) : SV_TARGET
{
float4 color = colorTex.Sample( texSamp, input.tex );
// float depthValue;
// float4 color;
// depthValue = input.lightParam.z / input.lightParam.w;
// color = float4((depthValue-0.9)*10.0f, 0.0f, 0.0f, 1.0f);

return color;
}

here are 2 screenshots (ignore the ugly texture in the textured.jpg, its drawn as expected)
http://imageshack.us/g/200/depthq.jpg/
brighter red areas are drawn in front of darker red areas, as seen in textured.jpg,though they should actually be hidden by the black heightfield geometry. depth.jpg was taken with exactly the same setting as textured.jpg, only changed the comments in the pixel shader
Advertisement
I had a similar problem which was caused by my perspective projection calculation being done with a 0 for the near clipping plane distance. Check to see if this is the same case for you, and if so set it to a small value like .1 or so.
Moved to DX/XNA.
I'm not saying your doing your spaces wrong, but try just sending one matrix to the shader, the wvp (world * view * projection) then just multiply your vertices position with only that one matrix. I also had a problem with my depth buf$er before but I can't seem to remember what the problem was exactly right now, ill need to look at my code when I get back on my computer to refresh my memory.
Oh yeah, try commenting out the line where yiu set the depth stencil state, and see if that makes a difference. You shouldnt have to create the state because it should use the default dpth stencil state if you dont manually set it

This topic is closed to new replies.

Advertisement