• Advertisement
Sign in to follow this  

[D3D11] Weird depth bug

This topic is 2810 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

This is hard to describe so I've made a video to demonstrate the issue I've got here:
">YouTube link

At certain points in the terrain's rotation the depth of some pixels seems to "invert" i.e. Ones that would have passed the depth test begin to fail. It flicks between looking correct and looking wrong. It's not an instant flick either, as you will see in the video, the pixels will flip over in a strange horizontal sweep effect.

It happens even if the depth buffer is disabled =/ I've never encountered something like this before so I'm pretty stumped!

Share this post

Link to post
Share on other sites
Seems like depth testing is always disabled. Double-check your depth-setup and make sure the depth-test works for simpler geometry. Do you create and set a correct depth-stencil view (remember multi-sampling, if you use it), as well as a depth-stencil state?

Share this post

Link to post
Share on other sites
Here is my depth buffer setup:

D3D11_TEXTURE2D_DESC depthDesc;
depthDesc.Width = 800;
depthDesc.Height = 600;
depthDesc.MipLevels = 1;
depthDesc.ArraySize = 1;
depthDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
depthDesc.SampleDesc.Count = 1;
depthDesc.SampleDesc.Quality = 0;
depthDesc.Usage = D3D11_USAGE_DEFAULT;
depthDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
depthDesc.CPUAccessFlags = 0;
depthDesc.MiscFlags = 0;
ID3D11Texture2D *depthTexture;
mGraphicsDevice->CreateTexture2D(&depthDesc, NULL, &depthTexture);

descDSV.Flags = 0;
descDSV.Format = depthDesc.Format;
descDSV.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
descDSV.Texture2D.MipSlice = 0;
mGraphicsDevice->CreateDepthStencilView(depthTexture, &descDSV, &mDepthStencilBuffer);

D3D11_DEPTH_STENCIL_DESC depthStateDesc;
depthStateDesc.DepthEnable = true;
depthStateDesc.DepthWriteMask = D3D11_DEPTH_WRITE_MASK_ALL;
depthStateDesc.DepthFunc = D3D11_COMPARISON_LESS_EQUAL ;
depthStateDesc.StencilEnable = false;
depthStateDesc.StencilReadMask = 0;
depthStateDesc.StencilWriteMask = 0;
ID3D11DepthStencilState *depthState;
mGraphicsDevice->CreateDepthStencilState(&depthStateDesc, &depthState);
mGraphicsContext->OMSetDepthStencilState(&depthState, 0);

mGraphicsContext->OMSetRenderTargets(1, &mRenderTargetView, mDepthStencilBuffer);

I don't know if there's anything wrong with that. I'm still getting to grips migrating to D3D11!

Share this post

Link to post
Share on other sites
You seem to have an error here:
mGraphicsContext->OMSetDepthStencilState(&depthState, 0);
There should be no & before depthState.

If it still doesn't work, how do you set up your render-target?
The depth buffer should match exactly the render-target, including multi-sampling if it is used.

I see you don't check return values. Make sure your calls actually succeed.
Do you enable debugging?
Use the D3D11_CREATE_DEVICE_DEBUG flag when creating the device, and run with debugging, and you will get warning messages if something is wrong.

Share this post

Link to post
Share on other sites
Ah the & is a copy paste error, that is not in the code I have here.
I do have the debug layer enabled and I am not receiving any errors, all the calls complete successfully.

I am getting the render target from the back buffer of the swap chain like this:

DXGI_MODE_DESC displayMode;
displayMode.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
displayMode.Height = 600;
DXGI_RATIONAL refreshRate;
refreshRate.Numerator = 60;
refreshRate.Denominator = 1;
displayMode.RefreshRate = refreshRate;
displayMode.Width = 800;

// Definition of the swap chain format data
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferDesc = displayMode;
swapChainDesc.Flags = 0;
swapChainDesc.OutputWindow = mWindow;
sampleDesc.Count = 1;
sampleDesc.Quality = 0;
swapChainDesc.SampleDesc = sampleDesc;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Windowed = true;

HRESULT result = D3D11CreateDeviceAndSwapChain(0, D3D_DRIVER_TYPE_HARDWARE, 0, D3D11_CREATE_DEVICE_DEBUG, featureLevels, 6,
D3D11_SDK_VERSION, &swapChainDesc, &mSwapChain, &mGraphicsDevice, 0, &mGraphicsContext);
if(result != S_OK)
AppStatus::ErrorMessage = "Could not create Direct3D 11 device and swap chain";
return false;

mSwapChain->GetBuffer(0, __uuidof(mRenderTargetTexture), (void **)&mRenderTargetTexture);

mGraphicsDevice->CreateRenderTargetView(mRenderTargetTexture, 0, &mRenderTargetView);

Share this post

Link to post
Share on other sites
Here is a picture of the strangeness mid "sweep":

At this point the parts that should be showing are being overwritten by the pixels behind which should not be happening.

Share this post

Link to post
Share on other sites
For some reason your depth test doesn't appear to be working, and I think the ordering of your vertices rotating around (and hence changing the drawing order) is causing a switch in which pixels get culled. It looks like the shading goes from dark to light when the sweep occurs, which would make sense if a back facing pixel was getting culled out away from a front facing one.

Have you tried using PIX to inspect the contents of the depth buffer before and after each draw call? Specifically, make sure you are clearing the depth buffer, and that you see its contents changing correctly after each draw call. Also, I assume there are no debug messages on the console when you run the program, right?

Share this post

Link to post
Share on other sites
OK I've figured it out. Was a bit a weird but it turned out that the Z component of the output vertices was switching between being in and out of the visible projected view volume.

I fixed it by changing the depth function to Greater than or equal, clearing the depth buffer to 0 and dividing the Z component of all vertices by -W.

Still not entirely sure what's going on though. I'm gonna keep looking into it.

Share this post

Link to post
Share on other sites
I've done them manually by filling out a structure and mapping it to the shader constant buffer.

My projection matrix is this:

1.0f / tan(fov * 0.5f), 0, 0, 0
0, 1.0f / tan(fov * 0.5f), 0, 0
0, 0, (1000.0f) / (1000.0f - 0.1f), 1
0, 0, -((1000.0f) / (1000.0f - 0.1f)) * 0.1f, 0

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement