OpenGL中摄像机矩阵的计算原理

熟悉OpenGL|ES的朋友,可能会经常设置摄像机的view矩阵,iOS中相对较好,已经封装了方向,只需要设置摄像机位置,目标点位置以及UP向量即可。下面先介绍下摄像机view矩阵的计算原理。此处假设知道摄像机位置eye,目标点位置target以及UP向量。

主要是u,v,w三个向量的计算:

1. w向量: eye - target

2. u向量:向量UP与向量w的叉乘

3. v向量:向量w与向量u的叉乘

{

注意:向量叉乘不满足交换律,即(axb) != (bxa),结论是这两个结果向量的模相等,方向相反。

众所周知,两个向量叉乘得到一个垂直于这两个向量所在平面的向量。

axb:是从a向量旋转到b向量,根据左右手坐标系确定最终结果向量的方向。

bxa:是从b向量旋转到a向量,根据左右手坐标系确定最终结果向量的方向。

}

使用以上三个向量,按照 u , v , w 的顺序组建4*4的矩阵,当然上面提到的u,v,w向量都是vec3类型的,每个向量构建矩阵时还缺少第四个分量,接下来分别计算三个向量对应的值:

4. w向量的第四个分量:向量(-w)与eye的点乘

5. u向量的第四个分量:向量(-u)与eye的点乘

6. v向量的第四个分量:向量(-v)与eye的点乘

到此原理部分介绍完毕,下面给出iOS实现的代码:

 1 GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ,
 2                                 float centerX, float centerY, float centerZ,
 3                                 float upX, float upY, float upZ)
 4 {
 5     GLKVector3 ev = { eyeX, eyeY, eyeZ };
 6     GLKVector3 cv = { centerX, centerY, centerZ };
 7     GLKVector3 uv = { upX, upY, upZ };
 8     GLKVector3 w = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv)));//计算摄像机位置与目标点之间的向量,并进行规格化
 9     GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, w));
10     GLKVector3 v = GLKVector3CrossProduct(w, u);
11     
12     GLKMatrix4 m = { u.v[0], v.v[0], w.v[0], 0.0f,
13                      u.v[1], v.v[1], w.v[1], 0.0f,
14                      u.v[2], v.v[2], w.v[2], 0.0f,
15                      GLKVector3DotProduct(GLKVector3Negate(u), ev),
16                      GLKVector3DotProduct(GLKVector3Negate(v), ev),
17                      GLKVector3DotProduct(GLKVector3Negate(w), ev),
18                      1.0f };
19     
20     return m;
21 }

 

posted @ 2017-03-30 11:41  bky2016  阅读(1631)  评论(0编辑  收藏  举报