为什么从上面直接往下看一个形状的时候没有渲染?

问题描述 投票:-1回答:1

我把tutorial04.cpp从以下地方调整了一下 http:/www.opengl-tutorial.orgbeginners-tutorialstutorial-4-a-colored-cube

我做了一个金字塔的形状,我想把摄像机放在金字塔上面,然后向下看,但是我发现当摄像机直接在金字塔上面的时候,根本就没有渲染。如果我把X值改为0以外的其他值,它就能正常渲染。

Pyramid when camera is located at 1, 10, 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
};
c++ opengl glfw glm-math
1个回答
4
投票

不过你不是第一个上当的人,这种效果。链接

有两种解决办法。

  • 要么不使用 lookAt 功能,并用一个四元数来表示摄像机的旋转。
  • 或跟踪,从不应用 "直上"(0,X,0)或 "直下"(0,-X,0)的方向来观察你的摄像机。

问题到底出在哪里呢,我试着去研究一下 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),因为 upf 是准线,所以它们的交积为零,而且 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 有它的一个实现,所以使用它)。) 请记住,你不应该自己修改四元组的组件,否则它会变得无效,所以只能使用知道如何修改它们的函数)。)

顺便说一句,这完美地解释了为什么在电子游戏中,你不能把摄像头直接转到弓上射击,然后用头接箭。箭总是飞得有点偏离垂直方向,因为你的相机从来都不是直直的。

© www.soinside.com 2019 - 2024. All rights reserved.