【问题标题】:Relate textures areas of a cube with the current Oculus viewport将立方体的纹理区域与当前 Oculus 视口相关联
【发布时间】:2016-04-05 00:46:44
【问题描述】:

我正在使用 Oculus rift SDK 创建一个 360° 图像播放器。 场景由一个立方体组成,摄像机位于立方体的中心,可以围绕偏航、俯仰和滚动进行旋转。

我使用 openGL 绘制了对象,并考虑了每个立方体面的 2D 纹理以创建 360° 效果。 我想找到原始纹理中某个瞬间实际显示在 Oculus 视口上的部分。

到目前为止,我的方法是尝试使用欧拉角找到视口的某个重要点(即中心点和角)的近似像素位置,以便识别原始纹理中的某些区域。

考虑到使用欧拉角的所有问题,这似乎不是最聪明的方法。

有没有更好的方法来完成它?

编辑


我做了一个可以在渲染循环中运行的小例子:

       //Keep the Orientation from Oculus (Point 1)
        OVR::Matrix4f rotation = Matrix4f(hmdState.HeadPose.ThePose);

        //Find the vector respect to a certain point in the viewport, in this case the center (Point 2)
        FovPort fov_viewport = FovPort::CreateFromRadians(hmdDesc.CameraFrustumHFovInRadians, hmdDesc.CameraFrustumVFovInRadians);
        Vector2f temp2f = fov_viewport.TanAngleToRendertargetNDC(Vector2f(0.0,0.0));// this values are the tangent in the center
        Vector3f vector_view = Vector3f(temp2f.x, temp2f.y, -1.0);// just add the third component , where is oriented
        vector_view.Normalize();

        //Apply the rotation (Point 3)
        Vector3f final_vect = rotation.Transform(vector_view);//seems the right operation.


        //An example to check if we are looking at the front face (Partial point 4)
        if (abs(final_vect.z) > abs(final_vect.x) && abs(final_vect.z) > abs(final_vect.y) && final_vect.z <0){  
          system("pause");
        }
  1. 是否应该考虑整个视口,还是应该为每只眼睛考虑?
  2. 如何指示视口相对于中心的不同点?我不太明白哪些值应该是 TanAngleToRendertargetNDC() 的输入。

【问题讨论】:

    标签: c++ opengl oculus


    【解决方案1】:

    您可以通过将相机位姿四元数传递给 OVR::Matrix4 构造函数来获得完整的旋转矩阵。

    您可以在眼睛视口中获取任何 2D 位置,并使用 fovPort tan 角度将其转换为其相机空间 3D 坐标。对其进行归一化,您将获得该像素在相机空间中的方向向量。

    如果你将之前得到的旋转矩阵应用到这个方向向量,你会得到那条射线的实际方向。

    现在你必须从这个方向转换到你的纹理 UV。方向向量中具有最高绝对值的组件将为您提供它正在查看的立方体的面。其余组件可用于查找纹理上的实际 2D 位置。这取决于您的立方体面的方向,是否为 x 翻转等。

    如果您在查看器的渲染部分,您将希望在着色器中执行此操作。如果这是为了找到用户在原始图像中看到的位置或其视野范围,那么就像您所写的那样,只有少数光线就足够了。

    编辑

    这里有一些代码可以从 tan 角度转换为相机空间坐标。

    float u = (x / eyeWidth) * (leftTan + rightTan) - leftTan;
    float v = (y / eyeHeight) * (upTan + downTan) - upTan;
    float w = 1.0f;
    

    xy 是像素坐标,eyeWidtheyeHeight 是眼睛缓冲区大小,*Tan 变量是 fovPort 值。我首先在 [0..1] 范围内表示像素坐标,然后按方向的总 tan 角对其进行缩放,然后重新定位。

    【讨论】:

    • 首先,感谢您的回答。我认为第一点可以解决:OVR::Matrix4f rotation = Matrix4f(hmdState.HeadPose.ThePose);对于第二点,我找不到某个2D位置的FovPort到3D向量的转换函数,可能你的意思是我必须自己实现。到目前为止,我只是使用函数 CreateFromRadians() 创建了 FovPort。
    • @Pelux:如果您将整个姿势传递给 Matrix4f 构造函数,您还将获得位置数据。如果你只想要旋转,你应该只传递姿势旋转组件(四元数)。回复:FovPort,是的,你必须实现它。一旦您了解了 FovPort tan 角度值所代表的含义,就很简单了。
    猜你喜欢
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    • 2014-05-06
    相关资源
    最近更新 更多