1

I tried to understand the mathematics behind the projection matrix and I found this page. The matrix from this page:

Matrix

I found this matrix is similar to the matrix of Xna.

I understood how they got to m33 and m44 columns of the matrix, but how they got to m11 and m22? And I didn't understand why I have to give the aspect ratio if I already give the field of view angle.

The last thing I want to know is: what is the equation for transfaring from ndc space to window space and how they get to this equation?

pimvdb
  • 151,816
  • 78
  • 307
  • 352
Just Nobody
  • 11
  • 1
  • 2
  • the link of the projection matrix picture is this: http://medialab.di.unipi.it/web/IUM/Waterloo/img284.gif – Just Nobody Mar 10 '12 at 13:13
  • This answer might help? http://stackoverflow.com/questions/28286057/trying-to-understand-the-math-behind-the-perspective-matrix-in-webgl/28301213#28301213 – gman Jun 25 '15 at 09:26

2 Answers2

0

You can change the field of view by just scaling the resulting x and y coordinates: you scale them up, you'll get smaller field of view (zoom in), you scale them down you'll get bigger field of view (zoom out). Perspective projection used in 3D software is rectilinear, so if your field of view is large enough the distortion at the edges will be severe, and you cannot have more than 180° field of view.

You need the aspect ratio, because the clip coordinates in OpenGL and Direct3D run from -1 to 1. In horizontal direction -1 is the left, 1 is the right. On vertical direction -1 is the bottom, 1 is the top. So if you want your squares really appear as a square, you'll need to scale down the X coordinate with the aspect ratio.

Calmarius
  • 18,570
  • 18
  • 110
  • 157
0

The FOV would be enough if screens were round... but they are rectangular so just the FOV isn't enough. The FOV is set for screen hieght and the other is the FOV times the ratio of screen width to height.

m11 can be though of as a way to scale the FOV in the width direction. m22 can be thought od as a way to scale the FOV in the height direction.

Steve H
  • 5,479
  • 4
  • 20
  • 26
  • Thanks for the quick response, but the scale to window fit is done when you tansfer to window space and multiply each x,y by this equation: 'xwin = ( xndc + 1 ) * width * 0.5 + x ywin = ( yndc + 1 ) * height * 0.5 + y' – Just Nobody Mar 10 '12 at 18:13
  • no, That code looks like what you would use to convert a position component (in -1 to +1 space, output of WVP after FOV consideration) to screen position depending on screen dimensions and also provides translational shift to place origin reference in top left corner. That has nothing to do with the FOV difference in the X & Y directions. Typically, that calc you just showed is done for you in the GPU pipeline between the vertex shader & pixel shader since your graphics device knows your viewport dimensions. Are you manually determining 2d screen positions of 3d locations? – Steve H Mar 11 '12 at 00:34
  • No, I'm just trying to understand how the "projection matrix" works, When we understand something, the more easy to work with. my question is why do I need to scale the x if its already done when we transform to screen position – Just Nobody Mar 11 '12 at 16:53
  • The projection matrix does not know your viewport dimensions (width & height in pixels) (it only knows aspect ratio of your viewport) when it transforms a 3d position to 2d screen position. So... it outputs a screen position from 0 to 1 (0 for left or top, 1 for right or bottom). The output may be like (0.25687, 0.67852). This is like ~25% to the right from the left edge & ~67% down the screen from the top. All the code does from your first comment is translates that to the actual pixel position for your particular viewport. But before all that... continued in next comment – Steve H Mar 11 '12 at 17:42
  • But before all that, to get to that initial result, it needs to know the width to height ratio of your squarish viewport so it can come up with the (0.25687, 0.67852) in the first place. The aspect ratio scales the FOV so that you actually have a larger FOV in width than in height. (in typical viewports that are wider than tall). So think of that as the part of the projection matrix that determines the width FOV vs. the height FOV. If the viewport were round and constant radius, both m11 & m22 would be 1. – Steve H Mar 11 '12 at 17:47
  • Sorry, not 1 but rather they would both be the same value (the angle of the FOV) – Steve H Mar 11 '12 at 17:50
  • I understand now. I have one more question and i hope it will be the last: The "fov" angle is used to determine the distance between the camera to the window projection plane? like in this picture?: http://www.codeproject.com/KB/windows-phone-7/3DGraphicsWP7/13.png – Just Nobody Mar 11 '12 at 18:31
  • Distance from the camera to the scene object in view space is the z component of the vector the projection matrix is being applied to. The way this distance factors into the FOV is that the projection matrix actually transforms the vector as a Vector4, not a vector3. The 4th component, w, goes into the operation as 1, gets operated on by those values in the lower right corner of the matrix that have depth (distance) information in them. After the transformation, the new x value is used by factoring it with the w value. continued next comment. – Steve H Mar 11 '12 at 21:13
  • When factored by that w component (which takes depth (distance) into consideration), if the result is greater than 1, it is farther to the right than the right extent of the screen. If less than -1, it is past the left extent of the screen. if 0, it is in the center of the screen... So the farther away from the camera (which would be noted in that w component) the greater the pre-transformed x component can be before reaching the viewport's extents... hope this helps. it's hard to know just the right words to help another person visualize something. – Steve H Mar 11 '12 at 21:20
  • there are 3 plane in the projection: "near" , "far" and the "window plane". the distance to the near and the far are given in the parameters as z-near and z-far, and this help me to get the transformed Z value between [0,1]. the transformed x and y are given with the ratio x-t=x*((window-plane-distance)/z). the x-t is the x after projection with perspective.the same with y. At least that's what I learned so please correct me if I have a mistake somewhere.continued next comment-> – Just Nobody Mar 11 '12 at 21:48
  • my question is if the (window-plane-distance is given by 1*cot(a/2) like in this picture: http://imageupload.org/en/file/198391/ffield-of-view-projection.png.html when e is the window-space-distance – Just Nobody Mar 11 '12 at 21:49
  • I just noticed a reference that indicates you can use either 1.) FOV to determine width/height projections *OR* 2.) viewport width & height values themselves... perhaps as you initially thought. Scroll halfway down here: http://msdn.microsoft.com/en-us/library/windows/desktop/bb147302(v=vs.85).aspx – Steve H Mar 12 '12 at 00:29
  • I found this: http://knol.google.com/k/perspective-transformation# and they show how they get the "x*(1/tan(fov/2)*z)" for m11 and m12 columns. Is this the real way to get the m11 and m12 columns? Is the field of view is used to get the half of the height or the width like they said? – Just Nobody Mar 12 '12 at 18:46
  • That is not consistent with my understanding. I've never seen z be a factor in m11 or m22. – Steve H Mar 12 '12 at 23:02
  • after the projection transformation, the w component gets the z value before the projection, and then we divide the vector to get ndc vector. the x , y and the z values are divided by the w component which equal to the z value before projection transformation. so the z isnt a factor in m11 or m22, but it a factor in the 'w' dividing. if after the projection translation, the x value looks like this: x/(aspectRatio * cot(fov/2)) then after the W dividing, it will look like this: x/(aspectRatio * cot(fov/2) * w(=z befor projection)). It makes sense now, thank you for helping! – Just Nobody Mar 13 '12 at 16:55
  • Yes, that is exactly as I understand it and what I was trying to convey in comment #8. Happy coding. – Steve H Mar 13 '12 at 19:52