顶点 OpenGL LookAt 未显示
Vertex OpenGL LookAt not showing
我正在使用 GLM 和 GLFW 绘制正方形。我有以下代码:
static const GLfloat g_vertex_buffer_data[] = {
// square
0, 0, 0,
1, 0, 0,
0, 0, 1,
1, 0, 0,
1, 0, 1,
0, 0, 1,
};
glm::mat4 Projection = glm::perspective(glm::radians(45.0f), (float)_width / (float)_height, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(glm::vec3(0.f, 5.f, 0.f), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 mvp = Projection * View * Model;
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
glm::mat4 MyModel = glm::mat4(1.0f);
glm::mat4 MyMVP = Projection * View * MyModel;
奇怪的地方就在这里:
glm::mat4 View = glm::lookAt(glm::vec3(0.f, 5.f, 0.f), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
现在,我什么也没看到。但是当我把它改成这个时:
glm::mat4 View = glm::lookAt(glm::vec3(0.f, 5.f, 0.000001f), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
然后我真的可以看到广场了。
为什么当我将 Z 坐标更改为零时我看不到它,为什么当我将它更改为 >0 时它会起作用?我实际上希望它为零(所以从 5 个单位到中心点看)但由于某种原因这不起作用。
---编辑---
这是glm::vec3(0.f, 5.f, 0.0000000000001f)
这是 glm::vec3(0.f, 5.f, 0.000000000000f)
的结果
所以你的lookat设置是错误的。您的相机当前从 (0,5,0) 指向 (0,0,0),向上矢量为 (0,1,0)。
这意味着您的相机正朝负 Y 方向看
normalize( (0,0,0) - (0,5,0) ) = (0,-1,0)
与向上矢量方向相同(倒置,但无关紧要)。显然你的相机不能指向与向上矢量相同的方向。
要解决您的问题,您只需使用向上向量 (0,0,1)。
这是正确设置相机后的场景。 XYZ 是世界参考(你也可以在那里看到你的四边形),UVN 是相机参考。 N 是视图方向,V 是向上矢量,U 是平行于 N 和 V 的侧向矢量。您实际上不必处理相机的 UVN 坐标,因为 GLM 会为您处理,您只需提供世界坐标中的中心点和眼点以及向上矢量。
如果您的向上矢量与视图方向相同,则它们不能正交并且相机参考未明确定义。
将中心点更改为 Z = 0.0000001f 而不是 0,使得向上矢量不完全平行于视图方向。 look at 函数的实现在某种程度上近似于您提供给实际向上向量的向上向量。这样做是为了让您不必在每次设置相机时都计算准确的向上矢量。
您只需指定向上矢量为 (0,0,1),如果您的观察方向恰好与向上矢量不正交,则 look at 会计算向上矢量的最佳近似值,以便UVN 向量仍然是正交的。除非向上矢量与视图方向重合,在这种情况下向上矢量可以是任何东西。
如果您不了解相机坐标、向上矢量等,请花时间 look/read 了解一下。 SO 中也有很好的答案。
我正在使用 GLM 和 GLFW 绘制正方形。我有以下代码:
static const GLfloat g_vertex_buffer_data[] = {
// square
0, 0, 0,
1, 0, 0,
0, 0, 1,
1, 0, 0,
1, 0, 1,
0, 0, 1,
};
glm::mat4 Projection = glm::perspective(glm::radians(45.0f), (float)_width / (float)_height, 0.1f, 100.0f);
glm::mat4 View = glm::lookAt(glm::vec3(0.f, 5.f, 0.f), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
glm::mat4 Model = glm::mat4(1.0f);
glm::mat4 mvp = Projection * View * Model;
GLuint MatrixID = glGetUniformLocation(programID, "MVP");
glm::mat4 MyModel = glm::mat4(1.0f);
glm::mat4 MyMVP = Projection * View * MyModel;
奇怪的地方就在这里:
glm::mat4 View = glm::lookAt(glm::vec3(0.f, 5.f, 0.f), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
现在,我什么也没看到。但是当我把它改成这个时:
glm::mat4 View = glm::lookAt(glm::vec3(0.f, 5.f, 0.000001f), glm::vec3(0, 0, 0), glm::vec3(0, 1, 0));
然后我真的可以看到广场了。 为什么当我将 Z 坐标更改为零时我看不到它,为什么当我将它更改为 >0 时它会起作用?我实际上希望它为零(所以从 5 个单位到中心点看)但由于某种原因这不起作用。
---编辑---
这是glm::vec3(0.f, 5.f, 0.0000000000001f)
这是 glm::vec3(0.f, 5.f, 0.000000000000f)
所以你的lookat设置是错误的。您的相机当前从 (0,5,0) 指向 (0,0,0),向上矢量为 (0,1,0)。
这意味着您的相机正朝负 Y 方向看
normalize( (0,0,0) - (0,5,0) ) = (0,-1,0)
与向上矢量方向相同(倒置,但无关紧要)。显然你的相机不能指向与向上矢量相同的方向。
要解决您的问题,您只需使用向上向量 (0,0,1)。
这是正确设置相机后的场景。 XYZ 是世界参考(你也可以在那里看到你的四边形),UVN 是相机参考。 N 是视图方向,V 是向上矢量,U 是平行于 N 和 V 的侧向矢量。您实际上不必处理相机的 UVN 坐标,因为 GLM 会为您处理,您只需提供世界坐标中的中心点和眼点以及向上矢量。
如果您的向上矢量与视图方向相同,则它们不能正交并且相机参考未明确定义。
将中心点更改为 Z = 0.0000001f 而不是 0,使得向上矢量不完全平行于视图方向。 look at 函数的实现在某种程度上近似于您提供给实际向上向量的向上向量。这样做是为了让您不必在每次设置相机时都计算准确的向上矢量。
您只需指定向上矢量为 (0,0,1),如果您的观察方向恰好与向上矢量不正交,则 look at 会计算向上矢量的最佳近似值,以便UVN 向量仍然是正交的。除非向上矢量与视图方向重合,在这种情况下向上矢量可以是任何东西。
如果您不了解相机坐标、向上矢量等,请花时间 look/read 了解一下。 SO 中也有很好的答案。