LookAt (glm)返回错误的翻译z值

LookAt (glm) returns wrong translate z-value

本文关键字:翻译 错误 返回 glm LookAt      更新时间:2023-10-16

你好,我有一个问题与glm lookAt函数的返回值。当我在调试模式下执行时,我得到了这一点glm函数的 ... Result[3][2] = dot(f, eye); ...在矩阵的平移z轴位置上有一个错误的值。这个值是-2,这表明前矢量和眼矢量在相反的位置。我的eye, center和up向量是eye(0,0,2), center(0,0,1)和up(0,1,0)。凸轮坐标向量是:f(0,0,1), s(1,0,0)和u(0,1,0)。用户看到的有利位置是(0,0,0)。所以右视图矩阵应该是这个

1 0 0 0
0 0 0 0
0 0 1 0
0 0 0 1

但是我得到了这个:

1,,, 0, 0, 0,,
0 0,, 1,,,, 0
0 0,,,,,, 1,, 2
0 0,,,,,, 0,,, 1

我的代码是:
struct camera {
vec3 position = vec3(0.0f);         // position of the camera
vec3 view_direction = vec3(0.0f);   // forward vector (orientation)
vec3 side = vec3(0.0f);             // right vector (side)
vec3 up = vec3(0.0f, 1.0f, 0.0f);   // up vector
float speed = 0.1;
float yaw = 0.0f;                   // y-rotation
float cam_yaw_speed = 10.0f;        // 10 degrees per second
float pitch = 0.0f;                 // x-rotation
float roll = 0.0f;      
...
// calculate the orientation vector (forward) 
vec3 getOrientation(vec3 vantage_point) {
    // calc the difference and normalize the resulting vector
    vec3 result = vantage_point - position;
    result = normalize(result);
    return result;
}
// calculate the right (side) vector of the camera, by given orientation(forward) and up vectors
mat4 look_at_point(vec3 vantage_point) {
    view_direction = getOrientation(vantage_point);
    // calculate the lookat matrix
    return lookAt(position, position + view_direction, up);
}
};
我已经想了怎么处理这个问题,但还是不知道。有人能帮帮我吗?

我执行main_cam.look_at_point(vantage_point)函数的主函数如下所示:

...
GLfloat points[] = {
0.0f, 0.5f, 0.0f,
0.5f,  0.0f, 0.0f,
-0.5f, 0.0f, 0.0f };
float speed = 1.0f; // move at 1 unit per second
float last_position = 0.0f;
// init camera
main_cam.position = vec3(0.0f, 0.0f, 2.0f);         // don't start at zero, or will be too close
main_cam.speed = 1.0f;                              // 1 unit per second
main_cam.cam_yaw_speed = 10.0f;                     // 10 degrees per second
vec3 vantage_point = vec3(0.0f, 0.0f, 0.0f);
mat4 T = translate(mat4(1.0), main_cam.position);
//mat4 R = rotate(mat4(), -main_cam.yaw, vec3(0.0, 1.0, 0.0));
mat4 R = main_cam.look_at_point(vantage_point);
mat4 view_matrix = R * T;
// input variables
float near = 0.1f;      // clipping plane
float far = 100.0f;     // clipping plane
float fov = 67.0f * ONE_DEG_IN_RAD; // convert 67 degrees to radians
float aspect = (float)g_gl_width / (float)g_gl_height;  // aspect ratio
mat4 proj_matrix = perspective(fov, aspect, near, far);
use_shader_program(shader_program);
set_uniform_matrix4fv(shader_program, "view", 1, GL_FALSE, &view_matrix[0][0]);
set_uniform_matrix4fv(shader_program, "proj", 1, GL_FALSE, &proj_matrix[0][0]);
...

使用glm的旋转功能进行测试,三角形显示为右

带有glm旋转功能的三角形

我怀疑问题在这里:

mat4 view_matrix = R * T; // <---

lookAt返回的矩阵已经完成了转换。

尝试在三角形内部的(0,0,0)点上手动应用变换。T将其转换为(0,0,2),但现在它与摄像机重合,因此R将其发送回(0,0,0)。现在你在投影除法中偶然得到了一个除零。

所以删除乘法的T:

mat4 view_matrix = R;

现在(0,0,0)将被映射到(0,0,-2),这是在相机正在看的方向。(在相机空间中,投影中心位于(0,0,0),并且相机朝向负Z方向)。


EDIT:我想指出,从vantage_point计算view_direction,然后将position + view_direction反馈给lookAt是实现目标的一种相当人为的方式。你在getOrientation函数中做的是lookAt已经在里面做的。相反,您可以从lookAt的结果中获得view_direction:

mat4 look_at_point(vec3 vantage_point) {
    // calculate the lookat matrix
    mat4 M = lookAt(position, vantage_point, up);
    view_direction = -vec3(M[2][0], M[2][1], M[2][2]);
    return M;
}

然而,考虑到最终你试图实现偏航/俯仰/滚动相机控制,你最好不要使用lookAt