Sign in to follow this  
sirlemonhead

missing geometry - Possible z buffer issue?

Recommended Posts

sirlemonhead    227
I'm porting Aliens Vs Predator from a DirectDraw renderer to D3D8/9. I've got it mostly working fine on D3D8 but I notice rendering errors on certain levels. Level geometry would get over written, and objects behind walls would be visible (its not a transparency issue) I'm thinking something screwy is up with the z-buffer. I changed the code to d3d9 so I could use Pix, and here's what my scene looks like when presented: finished frame if you look at the wall that the left light source is attatched to, and compare it to the wall to the right, you'll notice a diagonal chunk of the wall is missing. here's a render output from Pix: before the wall chunk vanishes And then the next render output from pix: after the wall chunk vanishes As you can see, part of the wall vanishes. All i've done between these two updates is set a new texture and draw primitve. All I really want to know is if this looks like an issue with the Z Buffer? I clear it correctly, once at the start of the frame. Its set to Less_Equal. I'm using pre-transformed verts, no viewport. No D3D debug errors. I just really need a starting point so I can go through the code myself and try figure out what is causing this. Does it look like a z buffer issue? This problem doesnt happen in the original game code, and 99% of levels render fine with mine, so i'm a bit stumped..

Share this post


Link to post
Share on other sites
Imgelling    222
Could possibly be a face culling issue. Are all the triangles defined the same way (Clockwise/Counter-Clockwise)? Do you use back-face culling in the first picture?

Edit: Spelling.

Share this post


Link to post
Share on other sites
sirlemonhead    227
No, the game conveniently specifies them in whatever order it feels like :
So I've got culling permenantly set to none. I could probably re-arranged the order that triangles are drawn, but it'd break in game mirrors. Would it be worth testing, even though I've always got culling turned off?

Share this post


Link to post
Share on other sites
Imgelling    222
After a closer look at the photos, it does look like a drawing order problem (zbuffer). Open the second and third photos in different tabs in the browser and you can see the wall on top overwriting the bottom wall.

Hmm..do pre-transformed verts bypass the zbuffer test? Can you try using the painter's algorithm and see if that helps (simple back to front draw order). Other than that, I'm stumped. Hopefully someone more knowledgeable will come along.

Share this post


Link to post
Share on other sites
sirlemonhead    227
I see exactly what you mean, looking more closely. It is that top wall doing it.

pre-transformed doesn't bypass the test, as far as I know anyway..If I turn off z writes or z buffering, everything gets pretty messed up.

I'll see what I can do about draw order. The code is a bit hard to work with. I'm really just drawing things in whatever order the engine gives the vertex data to the rendering functions.

Are viewports needed for anything like this? The original code had one, but it was pre dx8 code, so I don't know If I need to reimplement it. Viewports should only really matter for clipping stuff that falls outside of my view range right?

Share this post


Link to post
Share on other sites
sirlemonhead    227
Ok, it seems that geometry is only being "drawn" to my z buffer if i'm standing right up next to it. If it's even farther than a short distance, nothing will be added to the zbuffer. All my geometry z values are within 0.0 and 1.0 so there's some value somewhere screwing this up..

do near and far clip planes come into play for pretransformed verts, if the final output is a z value within the correct range?

Share this post


Link to post
Share on other sites
sirlemonhead    227
Yeah, have a look at some of my z values

z-value: 0.986093
z-value: 0.986204
z-value: 0.986225
z-value: 0.986108
z-value: 0.986093
z-value: 0.986141
z-value: 0.986138
z-value: 0.986093
z-value: 0.986114
z-value: 0.986141
z-value: 0.986869
z-value: 0.986939
z-value: 0.986941
z-value: 0.986872
z-value: 0.986939
z-value: 0.987052
z-value: 0.987055
z-value: 0.986941
z-value: 0.986941
z-value: 0.986869
z-value: 0.986872
z-value: 0.986944
z-value: 0.986941
z-value: 0.987055
z-value: 0.987058
z-value: 0.986872
z-value: 0.987058
z-value: 0.986944

most of them are like this. I guess dx is discarding them as they're so close to 1.0

The original game has values this high too, so i don't know how that ever worked. using a 24bit z buffer but i guess the accuracy isnt high enough?

I have no idea where the znear and zfar are even set in this code.

Share this post


Link to post
Share on other sites
jollyjeffers    1570
With those sorts of Z-values I'd imagine its your projection matrix that is effectively flattening the scene and the rasterizer is actually seeing some or all of the geometry as coplanar.

How did you get those Z-values? Using PIX and going to the depth buffer? They look like they could be close enough (especially as depth is non-linear) to collide.

Quote:
I have no idea where the znear and zfar are even set in this code.
It's wherever you create the projection matrix - typically it'll be a D3DXMatrixPerspectiveFovLH() call. A very wide range or setting zNear to be 0.0 is a simple way of generating these sorts of errors. Depending on the scale of your geometry try setting them to something like 1.0 and 100.0 and experiment accordingly....

hth
Jack

Share this post


Link to post
Share on other sites
sirlemonhead    227
There's no D3DX stuff in this code unfortunatly. It was really old Dx stuff. software T&L and execute buffers.

void D3D_ZBufferedGouraudTexturedPolygon_Output(POLYHEADER *inputPolyPtr,RENDERVERTEX *renderVerticesPtr) is the function that gets passed all the main geometry. levels, objects, players gun. Everything but decals and particles more or less.

RENDERVERTEX defines my vertex data, and it uses ints for the x, y and z values.

So, an example of the kind of values I can see coming into this function for the vertexes Z value are:

5315
5239
6143
3972

etc.

Firstly in the function, a ZNear value is calculated.


// Get ZNear
ZNear = (float) (Global_VDB_Ptr->VDB_ClipZ * GlobalScale);




ZNear is always 64.000000 (VDB_ClipZ is 64 and GlobalScale is 1)

The code then does

float oneOverZ = 1.0/(float)vertices->Z;




oneOverZ has values typically like

0.000156
0.000163
0.000162
0.000149

then the code does this

float zvalue = (float)vertices->Z+HeadUpDisplayZOffset;




HeadUpDisplayZOffset is defined as '0'

zvalue has values such as

6710.000000 (if vertices->Z was 6710)
etc

then

zvalue = 1.0f - ZNear/zvalue;




which has values such as

0.990462
0.990462
0.991779

which are the values that end up being set as z value of my vertex data inside the vertex buffer I use to render

so I don't get to set a ZNear and ZFar as such.

It's really confusing code to work with :

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this