Jump to content
  • Advertisement
Sign in to follow this  

Reverse projection

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


I am stuck on a math problem at the moment. I want to project 2D screen coordinates to a plane in 3D view space which is parallel to the view plane and has got a particular distance.
Let's suppose I have got a 2D point P[sub]2[/sub](x, y) on my view plane. My resolution is 800x600, so my x is ranging from 0 to 800 and my y from 0 to 600. I define a distance d[sub]z[/sub] which the plane in 3D view space and the view plane should have. Now I want to estimate the the 3D point P[sub]3[/sub] (x', y', z') in view space on that specific plane with distance d[sub]z[/sub] to my view plane.

A projection matrix is given:
XMMATRIX projMatrix = XMMatrixPerspectiveFovLH(XM_PIDIV4, (float)(screenWidth) / (float)(screenHeight), 0.1f, 1000.0f);

The camera position vector camPos, the lookTo-vector and the up-vector are also given.

How do I estimate P[sub]3[/sub] now? I tried to calculate the differen coordinates like that:
z' = camPos + lookTo*d[sub]z[/sub]
x' = z' + cross(lookTo, up)*x
y = z' + up*y

The problem is, that due to perspective projection the plane in view space is bigger than the view plane itself and it gets bigger the bigger the distance d[sub]z[/sub] is between them. Thus when I got a big distance between those planes the projected plane on the on the view plane is very small and when I move my cursor to the right top corner to draw something for example it gets drawn somewhere in the middle of the screen.

I have to scale the x and y values somehow but I don't know how. Is there maybe another approach to solve this?

Share this post

Link to post
Share on other sites
Not exactly sure if this covers what you want but maybe it would work if you...

Travel down the 4 corners of your near plane in the view frustum a distance, d. This would provide you the width and height of your new plane. Then you could define a new frustum using those new dimensions and render to that.

The view frustum is a truncated pyramid (in perspective projection) so expect your width and height to increase.

Share this post

Link to post
Share on other sites
Yeah, this would be a great approach, but how do I estimate those 4 vectors and the 4 corners? I am aware that I can extract the 6 different planes which define the view frustum out of the projection matrix and thus just calculate their intersection line. But it seems quite elaborate and I am still missing those 4 corner points in 3D view space.

Share this post

Link to post
Share on other sites
Ok, now finally found a solution to solve this. I just post my approach so that everyone who has got the same problem can take this in consideration. ;)

I took a look at the initialization of my projection matrix. There i defined the field of view in angle, to be precisely it was PI/4 = 0.7853... defined by XM_PIDIV4:
XMMATRIX projMatrix = XMMatrixPerspectiveFovLH(XM_PIDIV4, (float)(screenWidth) / (float)(screenHeight), 0.01f, 100.0f);

As far as I have understood the perspective projection this value defines the field of view in radian angle in horizontal and vertical direction. So everytime I rotate my camera the field of view is streched around my lookTo vector by the angle XM_PIDIV4 in radian. Therefore my lookTo vector intersects with the center of every plane wich lies in the frustum and is parallel to the view plane.
With those information I did the following:
I took my up and right vector of my view space and generated rotation matrices which rotate around each of them with the angle XM_PIDV/2.0, just the half of my field of view:
XMMATRIX rotY = XMMatrixRotationAxis(up, XM_PIDIV4/1.3);
XMMATRIX rotX = XMMatrixRotationAxis(right, XM_PIDIV4/2.);
XMMATRIX rot_Y = XMMatrixRotationAxis(up, -XM_PIDIV4/1.3); //other direction
XMMATRIX rot_X = XMMatrixRotationAxis(right, -XM_PIDIV4/2.); //other direction

With those rotation matrices I took my lookTo vector and rotated him in such a way that I get all the four vectors which define the corners of my frustum:
XMVECTOR topleft, topright, bottomleft, bottomright;
topright = XMVector3Transform(lookTo, rotY);
topright = XMVector3Transform(topright, rot_X);
topleft = XMVector3Transform(lookTo, rot_Y);
topleft = XMVector3Transform(topleft, rot_X);
bottomright = XMVector3Transform(lookTo, rotY);
bottomright = XMVector3Transform(bottomright, rotX);
bottomleft = XMVector3Transform(lookTo, rot_Y);
bottomleft = XMVector3Transform(bottomleft, rotX);

Now it was possible to travel down on those vectors to get to the new corners of the plane which is parallel to the view plane. I used the mouse wheel to define the distance between both planes:
topright *= mouseZabsolute;
topleft *= mouseZabsolute;
bottomright *= mouseZabsolute;
bottomleft *= mouseZabsolute;

I haven't normalized the different vectors before, because my lookTo vector was already normalized.

In the next step I defined the right and up vector of the plane, so that their magnitudes are the width and height of the plane:
right = topleft - topright;
up = topleft - bottomleft;

Then I normalized the mouse coordinates which are in screen space
float normMouseX = (float)(-mouseXabsolute)/((float)(_screenWidth));
float normMouseY = (float)(-mouseYabsolute)/((float)(_screenHeight));

and used them to move my cursor on that plane:
cursor += camPos + topleft+normMouseX*right+normMouseY*up;

There is still one thing which bothers me. The rotation around the up vector must be adjusted everytime the aspect ratio changes. I found out that when the aspect ratio is 1.333 the somehow optimal rotation angle in radian is XM_PIDIV4/1.7 and when the aspect ratio is 1.777 the angle is XM_PIDIV4/1.3 . I can't figure out for now how to adjust this divisor properly.

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.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!