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 }