Jump to content
  • Advertisement
Sign in to follow this  
Maximus32

From clipping coordinates, back to eye coordinates

This topic is 3488 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 Everyone, I'm not sure if this question belongs here or in "Graphics Programming and Theory", so correct me if I'm wrong. I'm using a projection matrix to go from eye coordinates to clipping coordinates. In clip space fragments are clipped and new vertices are created. These new vertices do not have a Z value in eye coordinates. But I need that Z value for the deph buffer and perspective correct textures. I already tried lots of things like: a = (zFar - zNear) / 2; b = (zFar + zNear) / 2; ze = a * znd + b; How can I get the Z value from clip space (or normalized device space) back to eye space?

Share this post


Link to post
Share on other sites
Advertisement
The z dpeth is the percent in between 0 to 1 that gives the depth to the back clipping from the front so its really:

(zfar - znear) * zdepth = z depth in field of view.

You can take the wvp matrix, invert it and throw the cordinate back out into world space though fairly easy but then lack the speed of this op. Or the z part of xyz.

Share this post


Link to post
Share on other sites
I Just tried it and it's still looking bad. I think znear needs to added to get the correct value, but that also doesn't work.

Perhaps my clipping / normalized device values are messed up? I know the eye coordinates are good, so perhaps my projection matrix is wrong?

This is how I setup my Projection matrix, it should be exactly as in the OpenGL spec:

void
CAGLESMatrixF::glFrustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
{
GLfloat m[16];

GLfloat idw = 1.0f / (right - left);
GLfloat idh = 1.0f / (top - bottom);
GLfloat idz = 1.0f / (zFar - zNear);

m[0*4+0] = (2.0f * zNear) * idw;
m[0*4+1] = 0.0f;
m[0*4+2] = (right + left) * idw;
m[0*4+3] = 0.0f;

m[1*4+0] = 0.0f;
m[1*4+1] = (2.0f * zNear) * idh;
m[1*4+2] = (top + bottom) * idh;
m[1*4+3] = 0.0f;

m[2*4+0] = 0.0f;
m[2*4+1] = 0.0f;
m[2*4+2] = -((zFar + zNear) * idz);
m[2*4+3] = -((2.0f * zFar * zNear) * idz);

m[3*4+0] = 0.0f;
m[3*4+1] = 0.0f;
m[3*4+2] = -1.0f;
m[3*4+3] = 0.0f;

*pCurrentMatrix_ *= m;
}

EDIT: After lots of debugging it looks like the Z value in normalized device space is NOT linear?! It does have a range from 0(near) to 1(far).

[Edited by - Maximus32 on January 26, 2009 3:25:28 PM]

Share this post


Link to post
Share on other sites
Quote:
EDIT: After lots of debugging it looks like the Z value in normalized device space is NOT linear?! It does have a range from 0(near) to 1(far).


Distance from eye = Z*(Zf-Zn) + Zn

As you can tell from this equation, Z does not change linearly with distance, but 1/Z does. An inverse linear function like this is actually faster than exponential.

Share this post


Link to post
Share on other sites
Transform by the inverse of the projection matrix will convert from clip space to eye space.

Share this post


Link to post
Share on other sites
I finally figured out a fast way to get the eye coordinates, from the normalized device coordinates. Turns out z is already 1/z after the perspective division (from clipping-space to normalized-device-space). The formula for getting 1 / eye-z is:

ze = a * znd + b;

So that's the same I had all along, only difference is: I now get 1/ze instead of ze. Which is even better, because it saves me a division.

a = -0.5f * (1.0f / zNear_ - 1.0f / zFar_)
b = 0.5f * (1.0f / zNear_);

I don't really know what I'm doing here, matrix math is really complex. So if someone can tell me how I got 1/z without a division, I'd love to know.

But I do know it works, and it's fast! :-)

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!