码迷,mamicode.com
首页 > 其他好文 > 详细

<转载> OpenGL Projection Matrix

时间:2015-06-24 20:30:28      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

原文

OpenGL Projection Matrix

Related Topics: OpenGL Transformation

Updates: The MathML version is available here.

Overview

A computer monitor is a 2D surface. A 3D scene rendered by OpenGL must be projected onto the computer screen as a 2D image. GL_PROJECTION matrix is used for this projection transformation. First, it transforms all vertex data from the eye coordinates to the clip coordinates. Then, these clip coordinates are also transformed to the normalized device coordinates (NDC) by dividing with w component of the clip coordinates.

技术分享 
A triangle clipped by frustum

Therefore, we have to keep in mind that both clipping (frustum culling) and NDC transformations are integrated into GL_PROJECTIONmatrix. The following sections describe how to build the projection matrix from 6 parameters; leftrightbottomtopnear and farboundary values.

Note that the frustum culling (clipping) is performed in the clip coordinates, just before dividing by wc. The clip coordinates, xc, ycand zc are tested by comparing with wc. If any clip coordinate is less than -wc, or greater than wc, then the vertex will be discarded. 
技术分享

Then, OpenGL will reconstruct the edges of the polygon where clipping occurs.

Perspective Projection

技术分享 
Perspective Frustum and Normalized Device Coordinates (NDC)

In perspective projection, a 3D point in a truncated pyramid frustum (eye coordinates) is mapped to a cube (NDC); the range of x-coordinate from [l, r] to [-1, 1], the y-coordinate from [b, t] to [-1, 1] and the z-coordinate from [n, f] to [-1, 1].

Note that the eye coordinates are defined in the right-handed coordinate system, but NDC uses the left-handed coordinate system. That is, the camera at the origin is looking along -Z axis in eye space, but it is looking along +Z axis in NDC. Since glFrustum() accepts only positive values of near and far distances, we need to negate them during the construction of GL_PROJECTION matrix.

In OpenGL, a 3D point in eye space is projected onto the near plane (projection plane). The following diagrams show how a point (xe, ye, ze) in eye space is projected to (xp, yp, zp) on the near plane.

技术分享 
Top View of Frustum
技术分享 
Side View of Frustum

From the top view of the frustum, the x-coordinate of eye space, xe is mapped to xp, which is calculated by using the ratio of similar triangles; 
技术分享

From the side view of the frustum, yp is also calculated in a similar way; 
技术分享

Note that both xp and yp depend on ze; they are inversely propotional to -ze. In other words, they are both divided by -ze. It is a very first clue to construct GL_PROJECTION matrix. After the eye coordinates are transformed by multiplying GL_PROJECTION matrix, the clip coordinates are still a homogeneous coordinates. It finally becomes the normalized device coordinates (NDC) by divided by the w-component of the clip coordinates. (See more details on OpenGL Transformation.
技术分享 ,  技术分享

Therefore, we can set the w-component of the clip coordinates as -ze. And, the 4th of GL_PROJECTION matrix becomes (0, 0, -1, 0). 
技术分享

Next, we map xp and yp to xn and yn of NDC with linear relationship; [l, r] ⇒ [-1, 1] and [b, t] ⇒ [-1, 1].

技术分享 
Mapping from xp to xn

技术分享

 

技术分享 
Mapping from yp to yn

技术分享

 

Then, we substitute xp and yp into the above equations.

技术分享
 
技术分享

Note that we make both terms of each equation divisible by -ze for perspective division (xc/wc, yc/wc). And we set wc to -ze earlier, and the terms inside parentheses become xc and yc of the clip coordiantes.

From these equations, we can find the 1st and 2nd rows of GL_PROJECTION matrix. 
技术分享

Now, we only have the 3rd row of GL_PROJECTION matrix to solve. Finding zn is a little different from others because ze in eye space is always projected to -n on the near plane. But we need unique z value for the clipping and depth test. Plus, we should be able to unproject (inverse transform) it. Since we know z does not depend on x or y value, we borrow w-component to find the relationship between zn and ze. Therefore, we can specify the 3rd row of GL_PROJECTION matrix like this. 
技术分享

In eye space, we equals to 1. Therefore, the equation becomes; 
技术分享

To find the coefficients, A and B, we use the (ze, zn) relation; (-n, -1) and (-f, 1), and put them into the above equation. 
技术分享

To solve the equations for A and B, rewrite eq.(1) for B; 
技术分享

Substitute eq.(1‘) to B in eq.(2), then solve for A; 
技术分享

Put A into eq.(1) to find B
技术分享

We found A and B. Therefore, the relation between ze and zn becomes; 
技术分享

Finally, we found all entries of GL_PROJECTION matrix. The complete projection matrix is; 
技术分享 
OpenGL Perspective Projection Matrix

This projection matrix is for a general frustum. If the viewing volume is symmetric, which is 技术分享 and 技术分享, then it can be simplified as; 
技术分享

Before we move on, please take a look at the relation between ze and zn, eq.(3) once again. You notice it is a rational function and is non-linear relationship between ze and zn. It means there is very high precision at thenear plane, but very little precision at the far plane. If the range [-n, -f] is getting larger, it causes a depth precision problem (z-fighting); a small change of ze around the far plane does not affect on zn value. The distance between n and f should be short as possible to minimize the depth buffer precision problem.

技术分享 
Comparison of Depth Buffer Precisions

Orthographic Projection

技术分享 
Orthographic Volume and Normalized Device Coordinates (NDC)

Constructing GL_PROJECTION matrix for orthographic projection is much simpler than perspective mode.

All xe, ye and ze components in eye space are linearly mapped to NDC. We just need to scale a rectangular volume to a cube, then move it to the origin. Let‘s find out the elements of GL_PROJECTION using linear relationship.

 

技术分享 
Mapping from xe to xn

技术分享

 

技术分享 
Mapping from ye to yn

技术分享

 

技术分享 
Mapping from ze to zn

技术分享

 

Since w-component is not necessary for orthographic projection, the 4th row of GL_PROJECTION matrix remains as (0, 0, 0, 1). Therefore, the complete GL_PROJECTION matrix for orthographic projection is; 
技术分享 
OpenGL Orthographic Projection Matrix

It can be further simplified if the viewing volume is symmetrical, 技术分享 and 技术分享
技术分享

<转载> OpenGL Projection Matrix

标签:

原文地址:http://www.cnblogs.com/cocox/p/4598313.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!