Jump to content
  • Advertisement
Sign in to follow this  
Magos

Z-buffer problems

This topic is 4839 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

I'm having problems with what seems to be a z-buffer problem. Faces are rendered in the wrong order. Here's a sample screenie: http://img368.imageshack.us/img368/238/pixelshadernormalmap7hb.jpg I have both D3DRS_ZENABLE and D3DRS_ZWRITEENABLE activated. EnableAutoDepthStencil is set to TRUE with the format D3DFMT_D32, D3DFMT_D24X8 or D3DFMT_D16 depending on the user capabilities (tested through CheckDeviceFormat()). The error exists both when using pixel/vertex shaders and without. Does anyone have any idea what might be wrong/missing? Not sure what code I could post either...

Share this post


Link to post
Share on other sites
Advertisement
you can use the <img src=".."> tags to embed images in posts


The usual one to try is checking the projection matrix. Particularly the "zNear" and "zFar" parameters. a near-plane value of less than 1.0f can cause numerical instabilities that will result in incorrect depth values. Equally, a large draw distance can affect the Z values generated - such that you want to get the zFar to be as close to the camera as is acceptable.

Also note that reducing the size of your mesh by a huge amount can cause incorrect depth values when the resolution is already limited..

Failing that, have you tried running against the debug runtimes (link in signiture if you don't know about these) to see if it's complaining about something?

hth
Jack

Share this post


Link to post
Share on other sites
It appears that your z-buffer is not enabled, though you wrote that it is. It also looks like maybe you are culling front faces instead of back faces, but its hard to tell.

Quote:
Original post by jollyjeffers
... Particularly the "zNear" and "zFar" parameters. a near-plane value of less than 1.0f can cause numerical instabilities that will result in incorrect depth values. Equally, a large draw distance can affect the Z values generated - such that you want to get the zFar to be as close to the camera as is acceptable.

That is not accurate. The near plane should be as far from the camera as possible, whether that distance is 1.0, 0.1, 0.0001, or 1000. The distance to the far plane has only a small effect on Z buffer resolution. In fact, setting the far plane at infinity is not unusual.

Share this post


Link to post
Share on other sites
Quote:
Original post by JohnBolton
It also looks like maybe you are culling front faces instead of back faces, but its hard to tell.

Good suggestion, but the spout of the teapot seems to rendered correctly - including the back-faces (visible through the very end) being culled.

Quote:
Original post by JohnBolton
Quote:
Original post by jollyjeffers
... Particularly the "zNear" and "zFar" parameters. a near-plane value of less than 1.0f can cause numerical instabilities that will result in incorrect depth values. Equally, a large draw distance can affect the Z values generated - such that you want to get the zFar to be as close to the camera as is acceptable.

That is not accurate. The near plane should be as far from the camera as possible, whether that distance is 1.0, 0.1, 0.0001, or 1000. The distance to the far plane has only a small effect on Z buffer resolution. In fact, setting the far plane at infinity is not unusual.

Fair point on the far plane, I do remember reading about the infinite projection trick with Carmack'ss reverse (think it was Carmack's reverse)..

But I was pretty sure that the zNear < 1.0f was correct - it's solved more than enough Z buffering issues in the past [smile]

hth
Jack

Share this post


Link to post
Share on other sites
I've tried different viewplanes, but no success. It's on 1->5000 currently, but I've gotten it to work on large intervals with no problems before. It's not the wrong culling, I've tried both.

I'm using swap chains, could there be something that might disrupt the z-buffer using these?

I get the feeling it's some really stupid mistake I've made (usually is when you've wrestled with something unsolvable for a few days ^^). I just have to find it...

Share this post


Link to post
Share on other sites
Since the screenshot says normalmap I take it you are working with a shader -- what does the pixelshader write?

Greetz,

Illco

Share this post


Link to post
Share on other sites
It's eventually supposed to be ambient + diffuse + specular lighting. At the time I was just checking what the normal-map the vertex shader sent to the pixel shader looked like (transformed into RGB) since apart from the problem explained above the lighting is also kinda odd, but that's a future problem ^^.

I doubt the shaders causes the problem since the z-buffer oddness is there even with shaders disabled...

Share this post


Link to post
Share on other sites
Ok, I found that resetting the device *may* solve it, but resetting again *may* return it to screwed-up again. It's quite random which seems rather odd.

I get the feeling my swap-chain system isn't quite as safe as it should be. When creating additional swap chains and/or resetting the device, can/should you use the same D3DPRESENT_PARAMETERS object or should each swap chain have their own? I noticed in the docs that some calls (especially Direct3DDevice->Reset()) sets some of the parameters to new values. Is there some good tutorial on swap chains (all I've read doesn't explain stuff like the questions above).

Share this post


Link to post
Share on other sites
I have basically two classes, "Graphics" which handles all graphics stuff (wrapper around Direct3D Device) and "GraphicsWindow" which is a wrapper around a swap chain (one for each window I have).

Called before each rendering session:


BOOL GRAPHICS::BeginRender(GRAPHICS_WINDOW& GraphicsWindow)
{
HRESULT Result;
LPDIRECT3DSWAPCHAIN9 SwapChain;

if(!Initialized)
{
Error.SetMessage("The Direct3D device is not initialized!");
return FALSE;
}

if(FAILED(Result = Direct3DDevice->TestCooperativeLevel()))
{
if(!DeviceLost) OnLostDevice();

DeviceLost = TRUE;

if(Result == D3DERR_DEVICELOST)
{
Error.SetMessage("The Direct3D device was lost!");
return FALSE;
}

if(FAILED(Direct3DDevice->Reset(&GraphicsInfo.DeviceInfo)))
{
Error.SetMessage("Unable to reset the Direct3D device!");
return FALSE;
}

SetRenderStates();
OnResetDevice();

Error.ClearMessage();

DeviceLost = FALSE;
}

CurrentGraphicsWindow = &GraphicsWindow;

SwapChain = CurrentGraphicsWindow->GetSwapChain();
if(SwapChain == NULL)
{
Error.SetMessage("Unable to retrieve the swap chain from the graphics window!");
return FALSE;
}

if(FAILED(SwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &BackBuffer)))
{
Error.SetMessage("Unable to retrieve the swap chain back buffer!");
return FALSE;
}

if(FAILED(Direct3DDevice->SetRenderTarget(0, BackBuffer)))
{
Error.SetMessage("Unable to set the swap chain back buffer as a render target!");
return FALSE;
}

ScreenWidth = CurrentGraphicsWindow->GetWidth();
ScreenHeight = CurrentGraphicsWindow->GetHeight();
ScreenAspect = CurrentGraphicsWindow->GetScreenAspect();

SetProjection();

Direct3DDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0);

if(FAILED(Direct3DDevice->BeginScene()))
{
Error.SetMessage("Unable to begin a new scene!");
return FALSE;
}

SetShader();
SetShaderConstants();

return TRUE;
}



Called after each rendering session:


VOID GRAPHICS::EndRender()
{
Direct3DDevice->EndScene();

CurrentGraphicsWindow->GetSwapChain()->Present(NULL, NULL, CurrentGraphicsWindow->GetWindow(), NULL, 0);
SAFE_RELEASE(BackBuffer);

CurrentGraphicsWindow = NULL;

ScreenWidth = 0;
ScreenHeight = 0;
ScreenAspect = 0.0f;
}



Creates the swap-chain:


BOOL GRAPHICS_WINDOW::Acquire()
{
LPDIRECT3DDEVICE9 Direct3DDevice;

Direct3DDevice = Graphics.GetDevice();
if(Direct3DDevice == NULL)
{
Error.SetMessage("Unable to retrieve the Direct3D device!");
return FALSE;
}

if(FAILED(Direct3DDevice->CreateAdditionalSwapChain(&GraphicsInfo.DeviceInfo, &SwapChain)))
{
Error.SetMessage("Unable to create a new swap chain!");
return FALSE;
}

return TRUE;
}



Anything suspicious?

Share this post


Link to post
Share on other sites
Ok, I seem to have solved it now. I had to manually create a z-buffer surface for each swap chain node.

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!