【问题标题】:What exactly is the UP vector in OpenGL's LookAt function?OpenGL 的 LookAt 函数中的 UP 向量到底是什么?
【发布时间】:2012-05-17 12:42:36
【问题描述】:

这与The LookAt target location doesn't matter if it is z = 0 or z = 1000 or -1000?有关

我试过了

    gluLookAt(512, 384, 2000,
              512, 384, 0,
              0.0f, 1.0f, 0.0f);

一切正常,现在我将第三行(UP 向量),最后一个数字更改为 0.8

    gluLookAt(512, 384, 2000,
              512, 384, 0,
              0.0f, 1.0f, 0.8f);

而且完全一样...接下来我尝试修改了第3行,第一个数字为0.8

    gluLookAt(512, 384, 2000,
              512, 384, 0,
              0.8f, 1.0f, 0.8f);

现在视图就像向左旋转了 45 度。这个 UP 矢量是如何工作的?

【问题讨论】:

    标签: opengl glulookat


    【解决方案1】:

    向上向量用于在提供给 gluLookAt 的眼睛和中心向量之间创建叉积。

    从 iOS 上的 GLKit 标头中,您可以看到实现如下:

    static __inline__ GLKMatrix4 GLKMatrix4MakeLookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ)
    {
        GLKVector3 ev = { eyeX, eyeY, eyeZ };
        GLKVector3 cv = { centerX, centerY, centerZ };
        GLKVector3 uv = { upX, upY, upZ };
        GLKVector3 n = GLKVector3Normalize(GLKVector3Add(ev, GLKVector3Negate(cv)));
        GLKVector3 u = GLKVector3Normalize(GLKVector3CrossProduct(uv, n));
        GLKVector3 v = GLKVector3CrossProduct(n, u);
    
        GLKMatrix4 m = { u.v[0], v.v[0], n.v[0], 0.0f,
            u.v[1], v.v[1], n.v[1], 0.0f,
            u.v[2], v.v[2], n.v[2], 0.0f,
            GLKVector3DotProduct(GLKVector3Negate(u), ev),
            GLKVector3DotProduct(GLKVector3Negate(v), ev),
            GLKVector3DotProduct(GLKVector3Negate(n), ev),
            1.0f };
    
        return m;
    }
    

    在这个问题How do I use gluLookAt properly? 中接受的答案很好地描述了向上向量的实际影响。

    (gluLookAt 中“向上”向量背后的直觉很简单:看任何东西。现在将头倾斜 90 度。你在哪里没有改变,你看的方向没有改变,但是你视网膜上的图像明显有。有什么区别?你的头顶指向哪里。那是向上的向量。)

    【讨论】:

      【解决方案2】:

      向上向量确定哪个方向是“向上”。把它想象成一台摄像机......如果你“正确”握住摄像机,那么一条从摄像机中心向上延伸到摄像机顶部的假想线可以用一个向量 (0,1,0) 表示.如果您将相机向右倾斜 45 度,则从相机中心到相机“顶部”的假想线现在将由一个新向量 (1,1,0) 表示。如果您将相机“向后”倾斜一点,您的“向上”矢量现在变为(1,1,1)[或(1,1,-1)......我总是得到z轴的极性反转]。

      因此,简而言之,UP 向量通过说明相机方向中哪个点“向上”来描述相机的滚动。

      希望对您有所帮助。 :)

      (根据评论编辑以更正摘要)

      【讨论】:

      • “所以,简而言之,UP 向量通过说明相机方向中哪个点“向上”来描述相机的俯仰、偏航和滚动。” 错误.向上只是滚动(偏航和俯仰受摄像机注视点的限制)。
      • 这可能是旧的,但谢谢你,这是迄今为止对我有意义的第一个解释!
      【解决方案3】:

      gluLookAt 的前两个参数是相机位置和相机目标。只有这两个,相机并没有完全受到限制。想象一下拿着相机站在某个地方。您可以水平握持相机拍摄风景照片,也可以垂直握持相机拍摄人像照片。在这两种情况下,相机的位置和图片主体的位置是相同的。您可以将相机旋转到任意角度,这两个值不会改变。第三个参数,向上向量,选择相机的方向。

      【讨论】:

        【解决方案4】:

        它的工作方式与看起来完全一样。

        想象你在太空中的某个点。他们会想象你正在从你的 -Z 方向直接看 2000 个单位的某个点。

        具有这些特征的可能的摄像机数量不计其数,但它们的不同仅在于具有不同的“向上”方向。因此,不同的“向上”方向对应于围绕视图方向具有不同的方向。

        向上矢量是与您希望相机具有的“向上”方向对齐的矢量方向。也就是说,如果您要从相机点绘制向上矢量,您会看到一条向上的垂直线。

        现在,回头看看你想象的视图,看看那条垂直线。你能分辨出那条垂直线是朝着你还是远离你?不;它只是一条垂直线。因此,向上矢量部分是否指向视图方向并不重要。重要的是向上的方向并不完全指向视图方向。

        当您给向上方向一个非零 Z 坐标时,它现在部分指向视图方向(即:Z 轴)。该部分最终与您获得的向上方向无关,因此被忽略。当你给向上方向一个非零的X坐标时,即在视图方向上不是,所以它很重要。

        这样做的目的是,如果您更改视图观察点或相机原点,您也不必更改向上方向。只要您不直接沿着上轴看,就可以了。

        【讨论】:

        • 如果我坐在椅子上直视前方,将 iPad 放在眼前,那么我的头顶就指向天空,因此 (0, 1, 0)... 如何关于如果我将其更改为(0, 0.00001, 1),那么这意味着我几乎是躺着了,现在我的脸和眼睛都朝向天空......那如果我使用(0, 1, 0),为什么结果完全一样?
        • @JeremyL:因为如果你躺着,脸和眼睛对着天空,你就不会再看 iPad。看到问题了吗?该函数必须弄清楚哪些是最重要的约束。就决定哪里而言,相机位置和观察位置胜过向上的方向。向上方向严格用于决定您要查看的位置之后的方向。改变向上的方向永远不会改变你正在看的地方,只会改变你在那个方向看的如何
        • 我的意思是,如果你几乎躺下,结果与坐在椅子上正对着正前方完全一样
        • @JeremyL:但事实并非如此。你不能躺着看着你直视前方时的同一点。必须优先考虑,而关注点就是这样做的。您仍然不明白向上矢量不会改变相机指向的方向。如果您想显示相机“躺下”,那么您必须更改观察点。
        猜你喜欢
        • 2017-07-19
        • 1970-01-01
        • 1970-01-01
        • 2015-10-20
        • 1970-01-01
        • 1970-01-01
        • 2020-07-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多