OpenGL中涉及到的矩阵变换

转自:https://blog.csdn.net/xyh930929/article/details/83715368

http://www.songho.ca/opengl/gl_camera.html

OpenGL Camera

Under Construction...

Related Topics: OpenGL TransformOpenGL Projection Matrix, Quaternion 
Download: OrbitCamera.ziptrackball.zip

Overview

OpenGL Eye Space 
OpenGL camera is always at origin and facing to -Z in eye space

OpenGL doesn't explicitly define neither camera object nor a specific matrix for camera transformation. Instead, OpenGL transforms the entire scene inversely to a space, where a fixed camera is at the origin (0,0,0) and always looking along -Z axis. This space is called eye space.

Because of this, OpenGL uses a single GL_MODELVIEW matrix for both object transformation to world space and camera (view) transformation to eye space.

You may break it down into 2 logical sub matrices; 
OpenGL ModelView matrix combined

That is, each object in a scene is transformed with its own Mmodel first, then the entire scene is transformed reversely with Mview. In this page, we will discuss only Mview for camera transformation in OpenGL.

LookAt

gluLookAt() is used to construct a viewing matrix where a camera is located at the eye position eye position and looking at (or rotating to) the target point target position. The eye position and target are defined in world space. This section describes how to implement the viewing matrix equivalent to gluLookAt().

Camera's looAt transformation consists of 2 transformations; translating the whole scene inversely from the eye position to the origin (MT), and then rotating the scene with reverse orientation (MR), so the camera is positioned at the origin and facing to the -Z axis. 
view matrix of lookAt

Camera lookAt animation 
OpenGL camera's lookAt() transformation

Suppose a camera is located at (2, 0, 3) and looking at (0, 0, 0) in world space. In order to construct the viewing matrix for this case, we need to translate the world to (-2, 0, -3) and rotate it about -33.7 degree along Y-axis. As a result, the virtual camera becomes facing to -Z axis at the origin.

The translation part of lookAt is easy. You simply move the camera position to the origin. The translation matrix MT would be (replacing the 4th coloumn with the negated eye position); 
lookAt's translation matrix

left, up and forward vector 
Left, Up and Forward vectors from target to eye

The rotation part MR of lookAt is much harder than translation because you have to calculate 1st, 2nd and 3rd columns of the rotation matrix all together.

First, compute the normalized forward vector forward vector from the target position vt to the eye position ve of the rotation matrix. Note that the forward vector is from the target to the eye position, not eye to target because the scene is actually rotated, not the camera is. 
forward vector

Second, compute the normalized left vector left vector by performing cross product with a given camera's up vector. If the up vector is not provided, you may use (0, 1, 0) by assuming the camera is straight up to +Y axis. 
left vector

Finally, re-calculate the normalized up vector up vector by doing cross product the forward and left vectors, so all 3 vectors are orthonormal (perpendicular and unit length). Note we do not normalize the up vector because the cross product of 2 perpendicular unit vectors also produces a unit vector. 
up vector

These 3 basis vectors, left vectorup vector and forward vector are used to construct the rotation matrix MR of lookAt, however, the rotation matrix must be inverted. Suppose a camera is located above a scene. The whole secene must rotate downward inversely, so the camera is facing to -Z axis. In a similar way, if the camera is located at the left of the scene, the scene should rotate to right in order to align the camera to -Z axis. The following diagrams show why the rotation matrix must be inverted.

Camera pitch animation 
The scene rotates downward if the camera is above

Camera yaw animation 
The scene rotates to right if the camera is at left

 

Therefore, the rotation part MR of lookAt is finding the rotation matrix from the target to the eye position, then invert it. And, the inverse matrix is equal to its transpose matrix because it is orthogonal which each column has unit length and perpendicular to the other column. 
Ratation matrix of lookAt

Finally, the view matrix for camera's lookAt transform is multiplying MT and MR together; 
OpenGL LookAt matrix

Here is C++ snippet to construct the view matrix for camera's lookAt transformation. Please see the details in OrbitCamera.cpp.


// dependency: Vector3 and Matrix4
struct Vector3
{
    float x;
    float y;
    float z;
};

class Matrix4
{
    float m[16];
}

///
// equivalent to gluLookAt()
// It returns 4x4 matrix
///
Matrix4 lookAt(Vector3& eye, Vector3& target, Vector3& upDir)
{
    // compute the forward vector from target to eye
    Vector3 forward = eye - target;
    forward.normalize();                 // make unit length

    // compute the left vector
    Vector3 left = upDir.cross(forward); // cross product
    left.normalize();

    // recompute the orthonormal up vector
    Vector3 up = forward.cross(left);    // cross product

    // init 4x4 matrix
    Matrix4 matrix;
    matrix.identity();

    // set rotation part, inverse rotation matrix: M^-1 = M^T for Euclidean transform
    matrix[0] = left.x;
    matrix[4] = left.y;
    matrix[8] = left.z;
    matrix[1] = up.x;
    matrix[5] = up.y;
    matrix[9] = up.z;
    matrix[2] = forward.x;
    matrix[6] = forward.y;
    matrix[10]= forward.z;

    // set translation part
    matrix[12]= -left.x * eye.x - left.y * eye.y - left.z * eye.z;
    matrix[13]= -up.x * eye.x - up.y * eye.y - up.z * eye.z;
    matrix[14]= -forward.x * eye.x - forward.y * eye.y - forward.z * eye.z;

    return matrix;
}

Rotation

 

Shifting

 

Forwarding

 

Example: OpenGL Orbit Camera

OpenGL OrbitCamera

Download source and binary: 
(Updated: 2017-12-14)

OrbitCamera.zip (include VS 2015 project)

Example: Trackball

OpenGL Trackball

Download: trackball.zip

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值