我把tutorial04.cpp从以下地方调整了一下 http:/www.opengl-tutorial.orgbeginners-tutorialstutorial-4-a-colored-cube
我做了一个金字塔的形状,我想把摄像机放在金字塔上面,然后向下看,但是我发现当摄像机直接在金字塔上面的时候,根本就没有渲染。如果我把X值改为0以外的其他值,它就能正常渲染。
如果我将X值设置为-0.0000001f或0.0000001f,它也能正常渲染。
下面的代码不工作。
glm::mat4 View = glm::lookAt(
glm::vec3(0,10,0), // Camera
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
这段代码可以正常工作
glm::mat4 View = glm::lookAt(
glm::vec3(1,10,0), // Camera
glm::vec3(0,0,0), // and looks at the origin
glm::vec3(0,1,0) // Head is up (set to 0,-1,0 to look upside-down)
);
我有5个点,我用它来画6个三角形。
a: 0,1,0
b: 1,0,-1
c: 1,0,1
d: -1,0,1
e: -1,0,-1
三角形1:a、b、c
三角形2:a、c、d
三角形3:a、e、b
三角形4:a、e、b
三角形5:b、d、c
三角形6:d、b、e
static const GLfloat g_vertex_buffer_data[] = {
0,1,0,
1,0,-1,
1,0,1,//a,b,c
0,1,0,
1,0,1,
-1,0,1,//a,c,d
0,1,0,
-1,0,1,
-1,0,-1,//a,d,e
0,1,0,
-1,0,-1,
1,0,-1,//a,e,b
1,0,-1,
-1,0,1,
1,0,1,//b,d,c
-1,0,1,
1,0,-1,
-1,0,-1//4,2,5
};
不过你不是第一个上当的人,这种效果。链接
有两种解决办法。
lookAt
功能,并用一个四元数来表示摄像机的旋转。问题到底出在哪里呢,我试着去研究一下 glm
代码,还有就是如何 lookAt
看起来
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);
Result[3][1] = -dot(u, eye);
Result[3][2] = -dot(f, eye);
return Result;
}
如果你的相机直直地向上或向下看,那么 f
将是(0,1,0)。s
将永远是(0,0,0),因为 up
和 f
是准线,所以它们的交积为零,而且 u
也是(0,0,0),因为 s
是。所以你得到的结果矩阵是。
[0 0 0 0]
[0 0 1 0]
[0 0 0 0]
[0 0 0 1]
如果你懂一些线性代数,你就会知道这个矩阵的等级是2, 当它被应用于图形旋转和平移时, 它就会把你看到的所有东西折叠成一个低维线性空间(我对数学没有信心,但这是我的想法)。你基本上失去了一个或多个维度的3D空间,当它投射到你的2D屏幕上时,你可能会看到一个1D图像,这是一条细线,根本看不到。
这可能也是一个隐含的特殊情况,即在你的屏幕上,你可能会看到一条细线。万向节锁 - 当直观的 "X-Y-Z "旋转可能最终失去1个或更多的自由度时,就会产生这样的效果,使得空间无法 "解旋 "回来。这就是四元数的作用,它们不会受到Gimbal Lock的影响,与mat4相比,它们需要更少的内存来存储,它们计算速度更快,它们更难解释和理解(但 glm
有它的一个实现,所以使用它)。) 请记住,你不应该自己修改四元组的组件,否则它会变得无效,所以只能使用知道如何修改它们的函数)。)
顺便说一句,这完美地解释了为什么在电子游戏中,你不能把摄像头直接转到弓上射击,然后用头接箭。箭总是飞得有点偏离垂直方向,因为你的相机从来都不是直直的。