Help me to understand Clipping & Z-Buffer

Started by
12 comments, last by MJP 15 years, 9 months ago
Hi, i'm fighting against the proj matrix :) Objective: display a planet with a ring using a realistic coordinate system. For example Saturn. I create the projection matrix and, to increase the precision, i set the near clip and far clip just above and behind the planet.


D3DXMatrixPerspectiveFovLH(&mProj, D3DX_PI * 0.25f, 1020.0f/738.0f,distance-radius, distance+radius);
HR(pD3dDevice->SetTransform(D3DTS_PROJECTION, &mProj)); 


where distance is the distance of the center of the planet to the origin (0,0,0) (where is setted the camera), and radius is the planet radius, including the ring. Putting near and far planet to distance-radius and distance+radius i should see all the planet whitout clipping. But the result is: ring is cutted How you can see, the ring is cutted. Now, i try to put the planet far away- also the planet now is cutted Now also the planet is cutted. I suspect a precision issue: in the first case the distance is = 3755313 (the u.m. is kilometers), in the second case is distance = 10088947. I've tried also an hack like:


D3DXMatrixPerspectiveFovLH(&mProj, D3DX_PI * 0.25f, 1020.0f/738.0f,distance-radius*2, distance+radius*2);
HR(pD3dDevice->SetTransform(D3DTS_PROJECTION, &mProj)); 


but it doesn't works... Some suggestions?
Advertisement
The near clipping plane is a plane, not a sphere. Therefore your code will only work if the planet is placed in the center of the cameras view, i.e at position [0, 0, z]. Otherwise the distance you are calculating to the planet is a diagonal distance and thus longer than it should be.
So to solve your problem, calclate the distance value as though the planet was at [0, 0, z].

So let me understand..

Suppose the planet has coordinates x,y,z
Fortunally, the camera has coordinate 0,0,0

now the distance that i compute is sqrt(x*x+y*y+z*z).
Have i to calculate as sqrt(0*0+0*0+z*z) = z?

No, there's something wrong.. if the planet is at (10000,0,0), and the camera is rotated to track it, i'll see at the center of the screen, but the distance is 10000, not 0!


[Edited by - PdG on July 11, 2008 6:47:23 AM]
Perhaps you should transform the planet's coordonate with the view matrix and apply the distance only with z.
Quote:Original post by Squallc
Perhaps you should transform the planet's coordonate with the view matrix and apply the distance only with z.


Unfortunally it doesn't works..

distance = abs(mView._31*coords.d3dCoords.x+mView._32*coords.d3dCoords.y+mView._33*coords.d3dCoords.z);D3DXMatrixPerspectiveFovLH(&mProj, D3DX_PI * 0.25f, 1020.0f/738.0f,distance-radius, distance+radius);HR(pD3dDevice->SetTransform(D3DTS_PROJECTION, &mProj)); 


(i need only to transform the z coordinate).
coords.d3dCoords is the directx coordinates of the planet.

And the result is:

still clipped

Rotating the camera, the clips effect vary again: (if the planet is at the center of the screen, it's well rendered, if it's near the corner, i obtain this issue.)

:(
The world matrix of the planet is the identity ?
Quote:Original post by Squallc
The world matrix of the planet is the identity ?


No.. if the planet has coordinate x,y,z, the world should be x00,0y0,00z, right?


Quote:Original post by PdG
No.. if the planet has coordinate x,y,z, the world should be x00,0y0,00z, right?


No a translation the matrix is
100X
010Y
001Z
0001

Quote:Original post by PdG
coords.d3dCoords is the directx coordinates of the planet.

Did you mean that these coordantes has been transformed by the world matrix of this planete ?
Quote:Original post by Squallc
Quote:Original post by PdG
No.. if the planet has coordinate x,y,z, the world should be x00,0y0,00z, right?


No a translation the matrix is
100X
010Y
001Z
0001

Quote:Original post by PdG
coords.d3dCoords is the directx coordinates of the planet.

Did you mean that these coordantes has been transformed by the world matrix of this planete ?


(sorry, i've made a mistake)

I mean that, for the planet, the world matrix is:

D3DXMatrixTranslation(&matWorld, coords.d3dCoords.x, coords.d3dCoords.y, coords.d3dCoords.z);

You might give this a try:

Assuming you know the camera's direction -

cdir = normalize(camera_direction_vector); // if camera direction is not normalized

pdir = normalize(planet_direction); // if camera is at (0,0,0), planet_direction = planet_position

nearZ = (distance_to_planet-radius) * cos( asin( cdir dot pdir ) );

EDIT: that will only be appox., now that I think about it. It doesn't take into account the vertical angle above/below centerline.

Is your camera upvector always (0,1,0)?

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

This topic is closed to new replies.

Advertisement