了解 GLM- openGL 中的相机转换

understanding camera translation in GLM- openGL

本文关键字:相机 转换 GLM- openGL 了解      更新时间:2023-10-16

openGL 的 GLM 数学库为构造lookAt matrix提供了这种实现。

template<typename T, qualifier Q>
GLM_FUNC_QUALIFIER mat<4, 4, T, Q> lookAtLH(vec<3, T, Q> const& eye, vec<3, T, Q> const& center, vec<3, T, Q> const& up)
{
vec<3, T, Q> const f(normalize(center - eye));
vec<3, T, Q> const s(normalize(cross(up, f)));
vec<3, T, Q> const u(cross(f, s));
mat<4, 4, T, Q> Result(1);
Result[0][0] = s.x;
Result[1][0] = s.y;
Result[2][0] = s.z;
Result[0][1] = u.x;
Result[1][1] = u.y;
Result[2][1] = u.z;
Result[0][2] = f.x;
Result[1][2] = f.y;
Result[2][2] = f.z;
Result[3][0] = -dot(s, eye);  //#this
Result[3][1] = -dot(u, eye);  //#this
Result[3][2] = -dot(f, eye);  //#this
return Result;
}

一切都很好,除了在我用//#this标记的最后三行中完成的翻译因素。平移必须针对相机的世界位置进行,x, y and z而是针对相机局部坐标和方向矢量的点积完成的,这不可能相等。

考虑一种情况,其中vector 2*eye(眼睛是相机的位置)作为vector center传递(中心是目标位置),然后相机的局部 z 轴将与方向矢量重合,从而为我们提供相机的平移因子作为[0,0,1],所以我们基本上只沿着z-axis沿着世界移动(因为我们不移动相机,我们将沿着 z 轴移动世界消极方向),这是我们不想要的。我在哪里错过了重点,或者为什么要这样做进行翻译?

glm::lookAt定义视图矩阵。视图矩阵将顶点坐标从世界空间转换为视图空间。
eyecenterup分别是世界空间中的位置向量,定义了相机在世界空间中的位置和方向。eyecenterup定义视图空间。如果通过此向量设置矩阵,则矩阵将从视图空间转换为世界空间。
由于视图矩阵必须做相反的事情(世界空间 ->视图空间),视图矩阵是该矩阵的逆矩阵,由eyecenterup定义。glm::lookAt是一种优化算法,用于计算这种空间情况下的逆矩阵。
注意suf在分配给矩阵时被转置。

逆矩阵的平移不是矩阵的负平移。逆矩阵的平移必须考虑方向(旋转)。因此,必须旋转平移向量。3x3 旋转矩阵对 (3d) 矢量的旋转可以通过轴矢量和方向矢量的 3 点积计算(与轴矢量的 3 点积相同)。(suf)定义一个3x3旋转矩阵,eye被这个矩阵变换。

代码的实际剂量是通过转置(suf)连接旋转和-eye的翻译(非常简化的伪代码):

viewmatrix = transpose(rotation(s, u, f)) * translation(-eye)

一个向量 a 与另一个归一化向量 n 的点积可以被认为是an的投影。所以,这里发生的一切是eye向量被投影到fsu上,它们是旋转坐标系的基础向量。通过这些投影,我们可以学习f-s-u坐标框中eyexyz坐标。