So much z-buffering !?!

Started by
4 comments, last by Namethatnobodyelsetook 16 years, 5 months ago
Dear guys, I find so much z-buffering in Direct3D: I'm totally confused. 1. To enable z-buffering, I have to create a device in this way ---presentParameters.EnableAutoDepthStencil = TRUE; ---presentParameters.AutoDepthStencilFormat = D3DFMT_D16; ---pIDirect3DSystem->CreateDevice( ..&presentParameters ...,&pDirect3DDevice) Later on I have to enable z-buffering with ---pDirect3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE ); 2. Setting a viewport is done with this ---D3DVIEWPORT9 viewPort; ---... ---viewPort.MinZ = ...; ---viewPort.MaxZ = ...; ---pDirect3DDevice->SetViewport( &viewPort ); 3. Setting a perspective is done with this ---D3DXMatrixPerspectiveFovLH( ...zmin, zmax ) 4. Did I forget anything? 5. I'm pretty confused. I can change some parameters whithout any change in behaviour other changes influence the result. Do you know any comprehensive tutorial which can help me? Thanks a lot in advance
Advertisement
What are the values of zmin and zmax? Try making your znear larger, to help with zfighting.

Also, you're using D16, which is a 16bit zbuffer (a total of 65536 different depth values, which isn't much at all). Try using a 24bit zbuffer (D24X8 or D24S8) instead.

If you still have problems, and can't find any other solution, you could look into using Linear Z-Buffering, but that should really only be the last option.

Hope this helps.
Sirob Yes.» - status: Work-O-Rama.
Quote:Original post by Tomerland
1.
To enable z-buffering, I have to create a device in this way

---presentParameters.EnableAutoDepthStencil = TRUE;
---presentParameters.AutoDepthStencilFormat = D3DFMT_D16;
---pIDirect3DSystem->CreateDevice( ..&presentParameters ...,&pDirect3DDevice)


Later on I have to enable z-buffering with
---pDirect3DDevice->SetRenderState( D3DRS_ZENABLE, D3DZB_TRUE );
Z-buffering will be enabled by default, you don't need to explicitly enable it with SetRenderState().

Quote:Original post by Tomerland
2.
Setting a viewport is done with this

---D3DVIEWPORT9 viewPort;
---...
---viewPort.MinZ = ...;
---viewPort.MaxZ = ...;
---pDirect3DDevice->SetViewport( &viewPort );
Usually these will be 0.0f and 1.0f. You only need to change these if you don't want to render to the whole render target.

Quote:Original post by Tomerland
3.
Setting a perspective is done with this
---D3DXMatrixPerspectiveFovLH( ...zmin, zmax )
Again, this will usually be 0.0f and 1.0f unless you're doing some "weird stuff".
EDIT: That's rubbish, ignore it [smile]
This is where you define your Z-buffer range for the near and far clip planes. The near clip should be as far away as possible (1.0f is reasonable), and not zero, and the far clip should be as close as possible. The larger the range between near and far clip planes, the lower the precision of the depth buffer. It's also worth noting that the Z-buffer range isn't linear; I don't remember the details exactly, but it's something like 70% of the buffer's precision is used in the first 30% of the the Z-range.

[Edited by - Evil Steve on October 31, 2007 7:38:29 AM]
Quote:Original post by Evil Steve
Quote:Original post by Tomerland
3.
Setting a perspective is done with this
---D3DXMatrixPerspectiveFovLH( ...zmin, zmax )
Again, this will usually be 0.0f and 1.0f unless you're doing some "weird stuff".


Are you sure about this? I'd expect setting zmin=0.0f and zmax=1.0f to do pretty "weird stuff". I'm pretty sure zmin should be set near to 1.0f and zmax, maybe 1000.0f. There's a good article on this here.
Quote:Original post by Trillian
Quote:Original post by Evil Steve
Quote:Original post by Tomerland
3.
Setting a perspective is done with this
---D3DXMatrixPerspectiveFovLH( ...zmin, zmax )
Again, this will usually be 0.0f and 1.0f unless you're doing some "weird stuff".


Are you sure about this? I'd expect setting zmin=0.0f and zmax=1.0f to do pretty "weird stuff". I'm pretty sure zmin should be set near to 1.0f and zmax, maybe 1000.0f. There's a good article on this here.

Arg, whoops - you're right. I haven't had my coffee yet [smile]
They are are all important steps..

1. I want a Z Buffer, and it should be n bits. The more bits the more accurate the stored Z values will be.

Later on, I want to actually use the Z buffer to reject pixels. You need this because at times you may want it off (rendering HUD, etc.)

2. Just like the viewport allows you to rescale a scene to use less of the X and Y range, it can be rescaled to use less of the Z range. This rescale occurs before Z testing. You could set min to 0.1f and max to 1, render your scene, then min to 0.0f and max to 0.1f, and render an object. This object will always appear above the scene, and will have Z buffering enabled, allowing for a concave meshes. It's a cheap way to saving having to clear the Z buffer in cases rare like this, with a cost of reduced Z buffer range.

3. Sets the near and far Z clipping planes.

4. You forget ZWRITEENABLE, and ZFUNC. ;) You can have ZENABLE set to reject pixels, while telling D3D not to store the Z of current pixel. Useful when you have lots of alphablended particles. ZFunc allows you to control which Z values cause a rejection. Typically you keep values that are less or equal (allows nearer objects, or multi-pass rendering on the same object).


The depth format controls the type of storage, much like going
char zbuffer[n];
long zbuffer[n];
except with 16 or 24 bit floating point types.

Object has Z values in model space.
After world transform, Z value is in world space.
After view transform, Z value is in view space.
After projection, Z value in in projection space.
The rasterizer will draw pixels between your polygon points.
(3) At this point, any visible pixel will have a Z/W between 0 and 1, where your near value has been mapped to 0, and your far value is mapped to 1.
(2)We then scale the results based on your viewport to be between MinZ and MaxZ.
(1,4)If ZEnable is true, we compare zbuffer[x,y] to your scaled Z value using ZFunc. (ie: if (zbuffer[x,y] <= 0.5), keep pixel)
(4)If ZWriteEnable is true, we store the new depth value. zbuffer[x,y]=newZ

This topic is closed to new replies.

Advertisement