Original post address: http://blog.csdn.net/popy007/article/details/4091967
In the previous article, we discussed the principle of Perspective Projection Transformation and analyzed the method for generating the Perspective Projection Matrix used by OpenGL. As we said, different graphic APIs cause matrix differences due to differences in the left-right coordinate system, vector column vector matrix, and transformation range. There can be dozens of different perspective projection matrices, however, their principles are similar. This time we are going to discuss the Perspective Projection Matrix of direct3d (d3d) for the following purposes:
(1) When writing a graphics engine, we need to use different graphics APIs. Currently, OpenGL and d3d are mainly used. Although the derivation of the two is extremely similar, the characteristics of d3d have led to some issues that need to be clarified.
(2) The DirectX SDK Manual provides some instructions on the perspective projection matrix, but it is not detailed or even has some errors, which makes it difficult for beginners to understand, this is the purpose of this Article.
This article aims to give readers a clear understanding of the principles of the d3d Perspective Projection Matrix, so as to know its differences with OpenGL and lay a solid foundation for building a cross-API graphics engine. One point to note is thatTo fully understand the content of this article, please first understand the content of the previous article "exploring Perspective Projection Transformation ".Because OpenGL and their perspective projection matrices are very similar in principle, we will not start from the basic knowledge in the previous article, but compare their differences to derive the transformation matrix. Let's get started!
OpenGLAndD3dBasic Differences
As mentioned above, the basic differences between different APIs lead to the differences in the final transformation matrix. The differences between OpenGL and d3d Perspective Projection matrices are as follows:
(1) OpenGL uses the right-hand coordinate system by default, while d3d uses the left-hand coordinate system by default.
(2) OpenGL uses column vector matrix multiplication while d3d uses row vector matrix multiplication.
(3) The Z range of OpenGL CVV is [-1, 1], and the Z range of d3d CVV is [0, 1].
These differences lead to the final differences between OpenGL and d3d Perspective Projection matrices.
D3dPivot projection matrix Derivation
Let's first look at the most basic perspective relationship diagram (the figure used at the beginning of the previous Article ):
Here we examine the relationship on the xz plane, and the relationship on the YZ plane is the same. Here, O is the camera position. NP is the near-cropping plane, also the projection plane, and N is the distance from it to the camera. FP is the far-cropping plane, and F is the position from it to the camera. P is the point to be projected, and p 'is the point after projection. According to the similarity triangle theorem, we have
Then there is
Note that OpenGL uses the right-hand coordinate system, so use-N (refer to this step in the previous article), while d3d uses the left-hand coordinate system, so use N, which isII. In this way, we get the point after projection.
The third information point is the position of the transformed Z on the projection plane, that is, N. It is useless. Let's write p'
Therefore, use the third useless information point to store Z (if you are not familiar with this, please refer to the previous article ). Next, we can find a and B to build CVV In the z direction. Note that here is another difference between OpenGL and d3d. The Z range of OpenGL CVV is [-1, 1], while that of d3d CVV is [0, 1]. That is to say, the point after Point Projection on the near-cropping plane in d3d will be on the z = 0 plane of CVV, the point after the point projection on the far crop plane is on the z = 1 plane of CVV. In this way, our calculation equation is
The first version of the perspective projection matrix is obtained.
That is
In this case, the third component is changed to CVV. The Z range of CVV is [0, 1]. Next, according to the previous article, we will change the first two components to CVV. The X and Y ranges of CVV are [-1, 1], as shown in:
Using Linear interpolation, we have:
Here left and right are the left and right ranges of the projection plane, and top and bottom are the upper and lower ranges of the projection plane. Xcvv and ycvv are the X and Y we need to calculate in the CVV case, that is, the result we want to calculate. But before calculating them, we should first write the above formula:
Note that if the projection plane is centered in the X direction
Then the first statement can be used to pin the 1/2 on both sides of the equal sign and write it
Similarly, if the projection plane is centered in the Y direction, the second formula can be written
We will discuss it in two cases:
(1) center of the projection plane and center of the x-y plane (center in both the X and Y directions)
(2) General situation
We discuss:
(1) Special Case Equation
This group is special, and the equation is relatively simple, but it is also the most frequently used method (this is used by d3dxmatrixperspectivelh, d3dxmatrixperspectivefovlh, d3dxmatrixperspectivefovlh, and week ). We export it:
Then we will introduce the Perspective Projection Matrix:
Where
R-L and T-B can be regarded as W and H of the projection plane respectively. The last matrix is one of the Perspective Projection matrices of d3d. In addition, if we do not know the right, left, top, and bottom parameters, we can also obtain them based on the FOV-field of view parameters. The following shows the relationship between two planes:
The two fovs are the field of view on the x-Z and Y-zplanes respectively. If only one field of view is given, the aspect ratio of the projection plane can be calculated as follows:
Use a field of view to calculate W or h, and then use the aspect ratio to calculate h or W.
(2) General Equation
This group of equations is cumbersome, but more general (consistent with the derivation of OpenGL General matrices, which is also used by d3dxmatrixperspectiveoffcenterlh and d3dxmatrixperspectiveoffcenterrh ). We export it:
We continue to introduce the Perspective Projection Matrix:
Where
The final matrix is the general perspective projection matrix of d3d.
Now, we have exported two pivot projection matrices of d3d. Next, I will write the Perspective Projection Matrix of OpenGL exported in the previous article. You can compare it with the general perspective projection matrix of d3d just exported.
After careful observation, we can find that the layout of the elements is a transpose relationship, which is caused by the differences between the left-right coordinate system and the row-column matrix they use. There are also differences in the details of some elements, because the Z range of CVV in d3d is different. It can be seen that, under the same principle, minor environmental differences can cause great changes, which is why there are many different versions of the perspective projection matrix. In general, the Perspective Projection Matrix can also be defined in the field of vision. The method is the same as in special cases.