• Advertisement
Sign in to follow this  

Help me to understand Clipping & Z-Buffer

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

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?

Share this post


Link to post
Share on other sites
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].

Share this post


Link to post
Share on other sites
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]

Share this post


Link to post
Share on other sites
Perhaps you should transform the planet's coordonate with the view matrix and apply the distance only with z.

Share this post


Link to post
Share on other sites
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.)

:(

Share this post


Link to post
Share on other sites
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?


Share this post


Link to post
Share on other sites
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 ?

Share this post


Link to post
Share on other sites
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);

Share this post


Link to post
Share on other sites
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)?

Share this post


Link to post
Share on other sites
This is really really simple:


D3DXVECTOR3 vPlanetPosViewSpace;
D3DXVec3TransformCoord(&vPlanetPosViewSpace, &vPlanetPos, &mView);
D3DXMatrixPerspectiveFovLH(... ,vPlanetPosViewSpace.z - radius, vPlanetPosViewSpace.z + radius);

Share this post


Link to post
Share on other sites
Quote:
Original post by MJP
This is really really simple:


D3DXVECTOR3 vPlanetPosViewSpace;
D3DXVec3TransformCoord(&vPlanetPosViewSpace, &vPlanetPos, &mView);
D3DXMatrixPerspectiveFovLH(... ,vPlanetPosViewSpace.z - radius, vPlanetPosViewSpace.z + radius);


God bless the united states! :)
It works!

Thank you!

Share this post


Link to post
Share on other sites
Quote:
Original post by Buckeye

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)?


No, you're in space and you can rotate on all three axis.

Anyway the solution of mjp seems to works.
I've to do a little adjustment with constant value (pheraps some precision problem with big number), but now it works.

Thank you anyway!

Share this post


Link to post
Share on other sites
Just a little explanation of what I did there...

The zNear and zFar parameters you pass to D3DXMatrixPerspectiveFovLH specify distance to two planes, which are perpendicular to the camera. Like this:



Since these planes are perpendicular, every point on one of these planes has the same z-coordinate with respect to the camera (the coordinate space relative to the camera is view-space). However while they have the same view-space z value, they don't have the same distance (as you've already noticed). So when we're trying to find good values for those two planes, we're looking for view-space z values rather than distance. Fortunately, it's very easy to calculate hits (as you saw in the code I posted).

Share this post


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

  • Advertisement