# 3D Position won't translate to 2D

My 3D Hero-Model is positioned at a certain point in 3D-Coordinates. Whenever he's colliding with a coin, I want to place an animated sprite sheet there. But my following implementation won't give me useful result.

Viewport vP = GraphicDevice.Viewport;
Vector3 unitPos = modelPos.LocalPosition;

Vector3 screenSpace = vP.Project(unitPos, _cam.Projection, _cam.View, Matrix.Identity);
MySprite sprite = new MySprite(unitPos.X, unitPos.Y);

//... Won't draw sprite where the model is


The sprites are almost at the exact position, but there's approx. a 100px difference. I am using a perspective camera with these settings:

Matrix Projection = Matrix.CreatePerspectiveFieldOfView((float)Math.PI / 3.0f, 800f / 480f, 1, 3000);


And when I place my camera to Z= 0 Y = 37 and Z = 220, I have to multiply the result of Vector3 by 3.

The position of my camera is a Vector3 though.

A is the pure calculated value for SpriteY and B is the calculated value *3 (coincidentally is the right position)

So, it isn't correct. Why???

• Does your MySprite constructor do anything non-standard with its inputs? 2D coordinates start from the upper-left corner, which might account for your inverted y coordinate. May 27, 2013 at 16:24
• I don't exactly know what you mean, but the only thing which is not working well is the Y-Axis of the sprite. It's a bit too low (see fig. A)
– IMX
May 27, 2013 at 19:05
• If your 2D coordinates use the default coordinate system, they have positive y pointing down. 3D coordinates frequently have positive y pointing up. Are you doing anything to account for that difference? May 27, 2013 at 19:10
• Other than the code above, I do nothing else. I just checked inverting the Y-Coordinates and its not a solution. Here's a thing you might find curious: The sprites only get drawn with an offset in a certain camera-setting. When I change the cam to some other setting (increasing Z and Y for instance), the sprites will match.
– IMX
May 27, 2013 at 19:14
• Multiplying by -1 will not the be solution, but neither will multiplying your camera vector by 3 or adding some values to it. You have a systematic problem that needs to be solved logically, not by random guess and check. May 27, 2013 at 19:20

You need to replace this code:

Vector3 screenSpace = vP.Project(unitPos, _cam.Projection, _cam.View, Matrix.Identity);
MySprite sprite = new MySprite(unitPos.X, unitPos.Y);


3D coordinates, even after projection, will still have their origin at the lower-right corner.

Texture coordinates, which your 2D system surely uses, start from the upper left, like so:

That means that you have to do some calculation other than your current code. For instance:

MySprite sprite = new MySprite(unitPos.X, GraphicsDevice.Viewport.Height - unitpos.Y);


However, this code is only for example. It will not be correct. You will also need to account for the position of your camera. If your camera ever points in a direction not parallel to the Z axis, the sprite position will be wrong.

To summarize, you will have to think quantitatively about what you are trying to accomplish, and write code that implements that math. Stop throwing code at the wall to see what sticks.

• Upvote. I agree on your point, about seeing the whole thing and judging by that. Still I think that I am almost there
– IMX
May 27, 2013 at 20:21