World Space to Screen space

Started by
2 comments, last by TtDTtW 17 years, 9 months ago
Hello all, I have a question about camera. If I have the view matrix and the perspective matrix of the camera, then I can construct my projection matrix. Then, 1. How can I determine whether a world space coordinate is on screen or not? 2. How can I determine how close a world space coordinate is going to be off/on of the screen? Is there any good tutorial online anyone can suggest to me about this topics? Thanks!
Nachi Lau (In Christ, I never die)www.sky-dio.com/Nachi
Advertisement
There are accessory functions to determine the conversion in most 3D APIs. For example you can use gluProject() and gluUnproject() to convert between world and screen coordinates with GL and Direct3D has D3DXVec3Unproject() and D3DXVec3Project().
Thanks for the suggestion. I know those functions. But the problem is that I am working in an environment which I have no access to those functions. It forces me to build from scratch.
Nachi Lau (In Christ, I never die)www.sky-dio.com/Nachi
Hey, I just did this... This all comes from understanding what the matrix is doing... Let's assume you're using DirectX...

Let V and P be your view and projection matrices (and world just be the identity).

So t is your transformed vertex which has an x,y,z,w component
(If v is only 3 dimension.. you need to give it a w of 1 before transforming it)

t = v*V*P

With how directX constructs their matrix, t.w will the depth (v.z of the untransformed matrix)
Now if you take...

t *= 1/(t.w); (If t.w == 0, it's an error obviously since that would mean the point is *right* on the camera)

Now, this will give us a new point
<x/w, y/w, z/w, 1> that's our *real* transformed to screen space coordinate... with screen space being a halfbox centered at the origin of size 2...
(thus it goes from [-1,1],[-1,1],[0,1])... (This makes sense since if you leave all your matries (view,work,proj) the identity, this would be your view frustrum...)

MSDN Visuals ^_^

So to detect if a point is inside or outside of this... it's as easy of doing a check if it's inside...

Here's code written from memory (and sadly I'm not by a computer with Visual Studio so it may have errors with me not remembering certain constant or function names exactly)

// LPDIRECT3DDEVICE9 pDevice   is our device// D3DXVECTOR3 v    is our vertex we're checkingD3DXMATRIX view, proj;pDevice->GetTransform( D3DTS_VIEW, &view );pDevice->GetTransform( D3DTS_PROJ, &proj );D3DXMATRIX trans = view * proj;   // I think the matrix struct has overloaded*D3DXVECTOR3 t;D3DXVec3Transform( &t, &v, &trans );  // vOut, vIn, matrix... right?if( t.z < 0.0 )      // with how proj works, this will be zero *now* if it's                     // near the near clip plane     return false;   // It appeared behind the camerat /= t.w;if( (abs(t.x) <= 1) && (abs(t.y) <= 1) && (t.z<=1) && (t.z >= 0) )     return true;// It's outside the boxreturn false;// If you want to see how *close* it is to being out... you could find out// which axis (x,y,z) is *farthest* from the cube, and return that distance// A more complex way is forming a ray from the point to the origin, and // intersecting it with all four sides, and return the distance to the closest// intersection


Again, someone should check me but I think that works. (Sorry about all the edits, my forum craft is rusty)

Also of note is that t.z will cluster near the [.9,1.0] range when all the math is done... this is why wBuffering gives better results the ZBuffering, since W is your actual depth and Z is your transformed depth...

[Edited by - TtDTtW on July 19, 2006 12:42:48 PM]
Network EngineerVolition Inc.

This topic is closed to new replies.

Advertisement