   Mapping vertex to screen coordinates
  HiI'm having an issue with something I thought would be very simple. I'm trying to map a rectangle made up out of 6 vertices to a the screen dimensions (so top left vertices to top left corner of the screen, and so on), by moving the vertices closer to the camera along the z-axis. What I'm looking for is a way to determine the amount I have to move the vertices closer to the camera. Sounds easy enough.Lets first make it a bit more concrete.I'm using the following view, and projection matrices:Matrix view = Matrix.LookAtLH(cameraPosition, new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));Matrix proj = Matrix.PerspectiveFovLH((float)Math.PI/4, aspectRatio, 1.0f, 100.0f);So basically I have the camera looking towards the positive z-axis.The coordinates of the vertices I'm trying to map to the screen are:(-0.5f * aspectRatio, 0.5f, -0.5f * aspectRatio)(0.5f * aspectRatio, -0.5f, -0.5f * aspectRatio)(-0.5f * aspectRatio, -0.5f, -0.5f * aspectRatio)(-0.5f * aspectRatio, 0.5f, -0.5f * aspectRatio)(0.5f * aspectRatio, 0.5f, -0.5f * aspectRatio)(0.5f * aspectRatio, -0.5f, -0.5f * aspectRatio)This basically defines a rectangle with height 1, and width the aspectRatio (equal to 1.777778 in my tests).Now what I'm looking for is a zTrans parameter to translate the world in the z direction so the upper left vertex maps to the top left corner of the screen.One way to get this would be some simple geometry; considering the plane formed by the X and Z axis, and by projecting the vertices on this plane using the Y axis. Make a triangle from the camera to the left vertices and a perpendicular corner to the rectangles base.  This provides enough information to get the depth that the rectangle should be at compared to the camera (vertices coincede with the screen corners, FOV information for the corner and half the width of the rectangle). Regarding the FOV, I haven't found the actual definition of the FOV parameter in the PerspectiveFovLH function; however I tried the 2 possibilities that are most logical (vertical FOV = 45deg and horizontal FOV=45deg), and both didn't result in an accurate value for the depth.What am I doing wrong, or how can I get an accurate value for translating the rectangle to match the screen dimensions (without changing the camera position and specs)? Thanks.   
  You might have better luck just using D3DXVec3Unproject() or changing the view to an orthographic projection. This depends on what your end goal is.   ;Quote:Original post by SiCraneYou might have better luck just using D3DXVec3Unproject() or changing the view to an orthographic projection. This depends on what your end goal is.I tried using the unproject function on the top left screen corner, however from this information I still need to derive the translation amount (basically making the angle between the vector returned by the unproject function and the vector of the top left vertex zero). I tried it this way, however couldn't get a correct value as well (came to something like 0.888 where it should be 0.91).   ;  So from what I gather, you just want to render a rectangle that perfectly sits across the whole screen.  Fortunately this is a common problem (usually done for full-screen post-processing), so there are common solutions.Anyway the trick here is that you don't need to use any sort of view or projection matrices to transform your vertices.  Since you already know where you want your vertices on your screen, you can simply specify exactly where you want them.  This is done by using the D3DFVF_XYZRHW FVF code (for fixed-function), or the D3DDECLUSAGE_POSITIONT declaration (for programmable pipeline).  Here's some code where I create a quad that fits nicely across my back-buffer:   //set up vertices for full-screen quadFLOAT fWidth5 = (FLOAT)backBufferW - 0.5f;FLOAT fHeight5 = (FLOAT)backBufferH - 0.5f;FLOAT fTexWidth1 = 1.0f;FLOAT fTexHeight1 = 1.0f; //create our vertex bufferd3dDevice->CreateVertexBuffer(sizeof(SCREEN_VERTEX) * 4, 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1,D3DPOOL_DEFAULT, &fullScreenQuadVB, NULL);SCREEN_VERTEX* vertices = NULL;fullScreenQuadVB->Lock(0, 0, (void**)&vertices, 0);// Fill in the vertex valuesvertices[0].pos = D3DXVECTOR4(fWidth5, -0.5f, 0.0f, 1.0f);vertices[0].clr = D3DXCOLOR(0.5f, 0.5f, 0.5f, 0.66666f);vertices[0].tex1 = D3DXVECTOR2(fTexWidth1, 0.0f);vertices[1].pos = D3DXVECTOR4(fWidth5, fHeight5, 0.0f, 1.0f);vertices[1].clr = D3DXCOLOR(0.5f, 0.5f, 0.5f, 0.66666f);vertices[1].tex1 = D3DXVECTOR2(fTexWidth1, fTexHeight1);vertices[2].pos = D3DXVECTOR4(-0.5f, -0.5f, 0.0f, 1.0f);vertices[2].clr = D3DXCOLOR(0.5f, 0.5f, 0.5f, 0.66666f);vertices[2].tex1 = D3DXVECTOR2(0.0f, 0.0f);vertices[3].pos = D3DXVECTOR4(-0.5f, fHeight5, 0.0f, 1.0f);vertices[3].clr = D3DXCOLOR(0.5f, 0.5f, 0.5f, 0.66666f);vertices[3].tex1 = D3DXVECTOR2(0.0f, fTexHeight1);fullScreenQuadVB->Unlock();Oh and by the way, the FOV parameter is the vertical FOV of your view frustrum.  Your horizontal FOV is aspectRatio * FOV.   ;  Trying to zero an angle is probably a wrong approach. Despite the name, D3DXVec3Unproject() doesn't actually return a vector, it returns a point. If you want a ray that determines the set of points that project to the upper left corner of the screen, then you can call it twice with two different depth coordinates and use those to parameterize a ray that you can then solve for your coordinates.Just what are you trying to do anyways? There may be an easier way that trying to translate a pre-existing rectangle.   ;  Thanks MJP and SiCrane for the answers.Quote:Original post by MJPSo from what I gather, you just want to render a rectangle that perfectly sits across the whole screen.  Fortunately this is a common problem (usually done for full-screen post-processing), so there are common solutions.Anyway the trick here is that you don't need to use any sort of view or projection matrices to transform your vertices.  Since you already know where you want your vertices on your screen, you can simply specify exactly where you want them.  This is done by using the D3DFVF_XYZRHW FVF code (for fixed-function), or the D3DDECLUSAGE_POSITIONT declaration (for programmable pipeline).  Here's some code where I create a quad that fits nicely across my back-buffer:*** Source Snippet Removed ***Oh and by the way, the FOV parameter is the vertical FOV of your view frustrum.  Your horizontal FOV is aspectRatio * FOV.The rectangle will not be fullscreen for the complete lifetime of the application. When the user presses a key, this rectangle will be zoomed out again, and an animation will occur (fully 3D; no 2D) to position the camera (well, moving the world) to the next rectangle that needs to be fullscreen. So I'm guessing using this method will get me into problems when the rectangle doesn't need to be positioned exactly on the screen. Quote:Original post by SiCraneTrying to zero an angle is probably a wrong approach. Despite the name, D3DXVec3Unproject() doesn't actually return a vector, it returns a point. If you want a ray that determines the set of points that project to the upper left corner of the screen, then you can call it twice with two different depth coordinates and use those to parameterize a ray that you can then solve for your coordinates.Just what are you trying to do anyways? There may be an easier way that trying to translate a pre-existing rectangle.Can't the point returned by the unproject function be interpreted as a vector (from the camera point (0,0,-3.0f) to the point returned)? It would seem this vector has the same angle as unprojecting 2 same 2D points with different z, and substracting these?I'm trying to move rectangles into fullscreen positions; these rectangles have different locations in space (with aspect ratios the same as your backbuffer) and only 1 rectangle is fullscreen at a time. There will be an animation in 3D when moving from 1 fullscreen rectangle to an other. This requires 2 parameters; the normal of the rectangle where the camera needs to be on (easy), and the distance the camera needs to be at to get it fullscreen.   ;  Break it down into simple parts.  Consider the width (in world coordinates) and the height (in world coordinates) of the rectangle.  To solve the equation, these widths and heights will equal the view frustum width and height at some distance away from the camera.1) Calculate the rectangle width/height (sounds like you have this down)2) This same width/height will exist in world space (you aren't scaling anything) when the rectangle is full screen.  So, it's simple trig from here.float w = rect_width, h = rect_height;float dist;dist = (h/2)/tan(VERT_FOV/2)If your aspect ratio of the rectangle matches that of the screen, you should get the same value for distance using the horizontal FOV (i.e. use whichever one you want).I just thought this out in my head, so it may not be completely accurate...but I think it should work.Chris   ;Quote:Original post by Supernat02Break it down into simple parts.  Consider the width (in world coordinates) and the height (in world coordinates) of the rectangle.  To solve the equation, these widths and heights will equal the view frustum width and height at some distance away from the camera.1) Calculate the rectangle width/height (sounds like you have this down)2) This same width/height will exist in world space (you aren't scaling anything) when the rectangle is full screen.  So, it's simple trig from here.float w = rect_width, h = rect_height;float dist;dist = (h/2)/tan(VERT_FOV/2)If your aspect ratio of the rectangle matches that of the screen, you should get the same value for distance using the horizontal FOV (i.e. use whichever one you want).I just thought this out in my head, so it may not be completely accurate...but I think it should work.ChrisChris, thanks!. This does indeed work. I had tried a similar method before; however I assumed the FOV was horizontal, and that you had to double the value to get the full FOV (read that somewhere else). Guess not :). Thanks again.   