mike74 100 Report post Posted July 17, 2005 Could someone give me a quick explanation of what a perspective matrix does? My understanding was that when you multiply a 3d point by it, it can convert it to a 2d location. If this is true, I don't see how it can do that. I thought you basically needed to divide by the z coordinate in order to do that, and there's no way a matrix can do that. Mike C. http://www.coolgroups.com/zoomer 0 Share this post Link to post Share on other sites
_Seb 122 Report post Posted July 17, 2005 You have to be aware that graphics device keeps all 3d points in the XYZW format, where W is 1 . ( It has nothing to do with RHW ! ). Then it is easier to multiply all the matrices which are 4x4, as you know. After that your point is normalized and looks like this : X/W Y/W Z/W . Now, let's look at the identity matrix:______*1 0 0 00 1 0 00 0 1 00 0 0 1If you don't change anything in the last column (*), you always get division by 1 and you can't notice where you can make it depend on Z. Now, let's set Z to 0 and get rid of division by W and change it into the division by Z. Look at the matrix:______*1 0 0 00 1 0 00 0 0 10 0 0 0Now. When the 3d point is multiplied, the result will be: X/Z Y/Z 0 . Try to do all the calculations by yourself to understand better.If you want to add screen width/height ratio, you need to (1,1) or (2,1) matrix element and get ( i.e. 1.333*X/Z Y/Z 0 or X/Z 0.75Y/Z 0 ) both correct for 800x600 screen ratio.Notice that (3,4) value of the matrix can be changed slightly in order to get different view angle. Now, you should see some more detailed description. I think that DirectX SDK has a good one. 0 Share this post Link to post Share on other sites
mike74 100 Report post Posted July 17, 2005 What do you mean by set z to 0? And, what do you mean by change it to division by z? If you set z to 0 and change it to division by z, isn't that division by zero?I'm really not following. If someone could clarify, that would be great. Mike C.http://www.coolgroups.com/zoomer 0 Share this post Link to post Share on other sites
JohnBolton 1372 Report post Posted July 17, 2005 The perspective divide is done after the projection transformation using the W value (which is computed by the projection transformation). 0 Share this post Link to post Share on other sites
JohnBolton 1372 Report post Posted July 17, 2005 Here is a simple perspective projection transformation matrix for OpenGL (note column vectors). The FOV is 90 degrees, the aspect ratio is 1:1, the near plane is at -1, and the far plane is at -infinity. 1 0 0 0 0 1 0 0 0 0 -1 -2 0 0 -1 0 [4, 4, -5, 1] ("view" or "eye" space) is transformed by the projection transformation to [4, 4, 3, 5] ("projection" or "clip" space), which is converted by the perspective divide to [.8, .8, .6] ("normalized device coordinates").Compare that to other points that would be drawn at the same place on the screen:[.8, .8, -1, 1] --> [.8, .8, -1, 1] --> [.8, .8, -1][1.6, 1.6, -2, 1] --> [.8, .8, 0, 2] --> [.8, .8, 0][8, 8, -10, 1] --> [8, 8, 8, 10] --> [.8, .8, .8][100, 100, -125, 1] --> [100, 100, 123, 125] --> [.8, .8, .984] 0 Share this post Link to post Share on other sites
_Seb 122 Report post Posted July 17, 2005 it should be 0 becouse there is no Z axis on your screen, is there ? Well, all the points are put on the XY plane ( your screen ). And their Z value is 0 ( presuably 0 is the valid value for DirectX, and OpenGL would like this value to be -1 ).I think, you have some problems with matrix multipling. As I showed in the previous reply, multiplication of the third column and a 3d point will result in 0 value. Furthermore, your graphic adapter will divide posttransformed points (X,Y,Z) by the result of multiplication of the last column and the point. So, as you can see, it is divided by Z :W value after transofrmation ( multiplication )X * 0 + Y * 0 + Z * 1 + W * 0 = ZZ value after transofrmationX * 0 + Y * 0 + Z * 0 + W * 0 = 0of course, there is no problem with dividing 0 with Z value. It always equals 0.There is something more. If you want to draw whole 3d scenes and use z-buffering, you can't set (3,3) value to 0, but you have to put there a previously calculated fraction which rescale the Z value to the desired range. For instance, 16bit deep z-buffer can contain values from 0 to 65535. We can calculate the fraction using near and far clipping plane. DirectX want values from (0;1) range ( They are converted to integers by the graphics adapter ).For example, your far clipping plane is 1000.0f form you and your near clipping plane is 4.0f from you. Then the fraction is 1.0f/(1000.0f-4.0f). Points outside this range ( 4.0f ; 1000.0f ) are eficiently rejected by the graphics adapter ).You can also notice that if you use 24 bit z-buffer, the computations will be more precise.If somehing is still unclear for you, feel free to ask. 0 Share this post Link to post Share on other sites
mike74 100 Report post Posted July 17, 2005 Seb, I'm pretty sure you got your matrix wrong. This is what you said was a perspective matrix.1 0 0 00 1 0 00 0 0 10 0 0 0Take a look at this:1 0 0 00 1 0 00 0 0 10 0 a 0I think the a has to be nonzero in order for the dividing by w to turn into division by z. What do you guys think?Also, one more thing. Let's say you have a z value of 0. How does OpenGL prevent division by 0? Does it just check if z is 0 and not do anything? (i.e. if you try to plot the point x,y,0, OpenGL won't produce a divide by 0 error)Mike C.http://www.coolgroups.com/zoomer 0 Share this post Link to post Share on other sites
JohnBolton 1372 Report post Posted July 18, 2005 Quote:Original post by mike74Let's say you have a z value of 0. How does OpenGL prevent division by 0? Does it just check if z is 0 and not do anything? (i.e. if you try to plot the point x,y,0, OpenGL won't produce a divide by 0 error)It is culled/clipped by the near plane. 0 Share this post Link to post Share on other sites
Quat 568 Report post Posted July 18, 2005 The perspective matrix does about 3 things:1. Elements [0][0] and [1][1] scale the x- and y-coordinates to simulate field of views other than 90. 2. It transforms the z-coordinate so that z-values in the range [near, far] are mapped to [0, far]. In this way, when you divide z later by w, you have 0 <= z' <= w ==> 0 <= z' / w <= 1, which is where it needs to be for depth buffering.3. It copies the original input z-coodinate into the output w-coordinate for later use by the homogeneous divide. 0 Share this post Link to post Share on other sites