View more

View more

View more

### Image of the Day Submit

IOTD | Top Screenshots

### The latest, straight to your Inbox.

Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.

# 3d position to 2d position

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

8 replies to this topic

### #1vivendi  Members

Posted 04 January 2012 - 04:08 PM

I want to convert a 3d position to a 2d screen coordinate. But i'm not really sure how to do that.

I know i need the view, projection and world matrix for the calculations. So i managed to get those. But what next? How can i calculate the 3d position of an object to a 2d screen position?

This is how i get the matrices:
[size="2"]D3DXVECTOR3 vector_2d, vector_3d(0,0,0);[/size]
[size="2"]D3DXMATRIX view_matrix, proj_matrix, world_matrix;[/size]
[size="2"]D3DVIEWPORT9 d3dvp;[/size]

[size="2"]dev->GetTransform( D3DTS_VIEW, &view_matrix );[/size]
[size="2"]dev->GetTransform( D3DTS_PROJECTION, &proj_matrix );[/size]
[size="2"]dev->GetTransform( D3DTS_WORLD, &world_matrix );[/size]
[size="2"]dev->GetViewport( &d3dvp );[/size]
[size="2"]D3DXVec3Project( &vector_2d, &vector_3d, &d3dvp, &proj_matrix, &view_matrix, &world_matrix );[/size]
[size="2"]D3DXVec3Unproject( &vector_3d, &vector_2d, &d3dvp, &proj_matrix, &view_matrix, &world_matrix );[/size]
[size="2"]
[/size]

### #2iedoc  GDNet+

Posted 04 January 2012 - 10:31 PM

The WordViewProjection matrix is what your looking for. that is the objects position in screen space, where x is -1 to 1, y is -1 to 1 and z is (assuming it's actually on the screen) 0 to 1, which is the depth.

to get the WVP, you just have to multiply the objects world space matrix with the view matrix, then with the projection matrix (in that order, World * View * Projection)

The world matrix stores the objects position (translation), orientation (rotation), and size (scale) in world space, or in other words, all the transformations you do on the model.

The View matrix stores the cameras position, target (what its looking at, or direction it's facing), and up (which is the direction that should be orthogonal to the target, so they make a right angle. it's the cameras "up" direction, and not the worlds up direction) You can get the view matrix from 3 vectors describing it like this:

D3DXMATRIX View;
D3DXVECTOR3 Position = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // Position of your camera
D3DXVECTOR3 Target = D3DXVECTOR3(0.0f, 0.0f, 1.0f);   // Cameras target
D3DXVECTOR3 Up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);	   // Cameras up, should be a unit vector, and orthogonal to Target

D3DXMatrixLookAtLH( &View, &Position, &Target, &Up );

The projection matrix is like a pyramid, where the camera is the point or top of the pyramid, and everything inside the pyramid is what the camera sees. The near and far planes decide how close to the camera and how far away from the camera objects should be clipped, or not rendered. You could look at the far plane as the base of the pyramid and the near plane like cutting the tip off of the pyramid, so that anything that's left inside the pyramid is rendered to the screen. The projection is defined by two floats that describe the near and far planes, an aspect ratio (width/height) and a vertical field of view (FOV, in radians). We can get the projection matrix like this: (notice the (float) next to Width/Height. This is because Width and Height are most likely integers, so without the (float) this would be an integer division, and the result would most likely be a 1 instead of a real aspect ratio)

D3DXMATRIX Projection;
D3DXMatrixPerspectiveFovLH(&Projection, 0.4f*3.14f, (float)Width/Height, 1.0f, 1000.0f);

Finally, after you have all three matrices, you can create the WVP, or world view projection matrix:

D3DXMATRIX WVP;
WVP = World * View * Projection;

The WVP matrix is the objects position in screen space. As i mentioned,above, screen space's x and y are between -1 and 1, and z is 0 to 1. If your looking to turn this into 0 to the width and height of your screen, you will have to do an extra calculation, which i will show you in a minute. Now that we have the WVP, we can get the objects screen space position like this:

D3DXVECTOR3 screenCoord = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // Position of object in screen space
D3DVec3TransformCoord(&screenCoord, &screenCoord, &WVP);

So now how do we turn the screen space from -1 to 1, to 0 to the width and height of your window? easy, just add 1 to x and y, divide it by two, and multiply it by the screen width or height, like this:

screenCoord.x = ((screenCoord.x + 1.0f) / 2.0f) * Width;
screenCoord.y = ((screenCoord.y + 1.0f) / 2.0f) * Height;

Maybe you already knew how to get the world, view, and projection matrices, but i thought i would be thorough and make sure you understand exactly how to do what you want ;)

hope this helps! good luck!
Braynzar Soft - DirectX Lessons & Game Programming Resources!

### #3Tsus  Members

Posted 05 January 2012 - 03:13 AM

Aloha,

Finally, after you have all three matrices, you can create the WVP, or world view projection matrix:

D3DXMATRIX WVP;
WVP = World * View * Projection;

The WVP matrix is the objects position in screen space. As i mentioned,above, screen space's x and y are between -1 and 1, and z is 0 to 1. If your looking to turn this into 0 to the width and height of your screen, you will have to do an extra calculation, which i will show you in a minute. Now that we have the WVP, we can get the objects screen space position like this:

D3DXVECTOR3 screenCoord = D3DXVECTOR3(0.0f, 0.0f, 0.0f); // Position of object in screen space
D3DVec3TransformCoord(&screenCoord, &screenCoord, &WVP);

So now how do we turn the screen space from -1 to 1, to 0 to the width and height of your window? easy, just add 1 to x and y, divide it by two, and multiply it by the screen width or height, like this:

screenCoord.x = ((screenCoord.x + 1.0f) / 2.0f) * Width;
screenCoord.y = ((screenCoord.y + 1.0f) / 2.0f) * Height;

This is exactly what D3DXVec3Project does. But for starters it is nice to see what is actually going on behind the scenes, so thumbs up for the time you spend. Besides, if you do those transformations in shaders you have to do it manually anyway.

Oh, and don't forget the flipping of the y coordinate, since the origin of the window is in a different corner:
screenCoord.y = ((-screenCoord.y + 1.0f) / 2.0f) * Height;
(Only necessary in D3D, not in GL as a side note...)

Greetings!

### #4iedoc  GDNet+

Posted 05 January 2012 - 03:56 AM

oh my bad! thanks for mentioning the flipping of y in screenspace!

i'm not going to lie, i wasn't even aware of D3DXVec3Project, haha, so thanks for that too, i'm pretty sure that's exactly what he's looking for, no sense recreating the wheel ;)
Braynzar Soft - DirectX Lessons & Game Programming Resources!

### #5vivendi  Members

Posted 05 January 2012 - 12:01 PM

Thanks alot guys. Thanks for the indept explanation, very much appreciated!

### #6vivendi  Members

Posted 05 January 2012 - 02:09 PM

Hi i still have a question. I though i had everything working but for some reason the screen coordinates are wrong.

This is my function:
D3DXMATRIX view_matrix, proj_matrix, world_matrix;
D3DVIEWPORT9 d3dvp;
D3DXVECTOR2 screen;

m_pD3Ddev->GetTransform( D3DTS_VIEW, &view_matrix );
m_pD3Ddev->GetTransform( D3DTS_PROJECTION, &proj_matrix );
m_pD3Ddev->GetTransform( D3DTS_WORLD, &world_matrix );
m_pD3Ddev->GetViewport( &d3dvp );
D3DXMATRIX WVP;
WVP = world_matrix * proj_matrix * view_matrix;

// Position of object in world
D3DXVECTOR3 screenCoord = D3DXVECTOR3(pos.x, pos.y, pos.z);

// Position of object in screen space
D3DXVec3TransformCoord(&screenCoord, &screenCoord, &WVP);

screenCoord.x = ((screenCoord.x + 1.0f) / 2.0f) * d3dvp.Width;
//screenCoord.y = ((screenCoord.y + 1.0f) / 2.0f) * d3dvp.Height;s
creenCoord.y = ((-screenCoord.y + 1.0f) / 2.0f) * d3dvp.Height;

// Put coords back in vector2s
creen.x = screenCoord.x;
screen.y = screenCoord.y;

return screen;


I position in my game is:
x:1211.037354 y:-411.112854 z:232.125015

The screen result is:
620563.125000 y:158251.343750

Which i weird, because the object was exactly infront of me. Any idea where it goes wrong?

### #7Tsus  Members

Posted 05 January 2012 - 03:26 PM

The transformation order should be:
WVP = world_matrix * view_matrix * proj_matrix;

You can compare the result to what D3DXVec3Project is giving you. It should yield the same.

### #8AngryWill  Members

Posted 12 April 2012 - 12:17 AM

need to divide by the w coordinate also, as in:

vec4f v4Position(v3ObjectPos.x, v3ObjectPos.y, v3ObjectPos.z, 1.f);
v4ScreenPosition = v4Position * WorldViewProjectionMatrix;
v4ScreenPosition.x /= v4ScreenPosition.w;
v4ScreenPosition.y /= v4ScreenPosition.w;
v4ScreenPosition.x = fScreenWidth * (v4ScreenPosition.x+1.0f)/2.f;
v4ScreenPosition.y = fSreenHeight * (1.0f-((v4ScreenPosition.y+1.f)/2.f));


### #9Anddos  Members

Posted 12 April 2012 - 03:05 AM

try setting the world matrix to the indentity

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.