如何在XNA中计算Oculus Rift的3D视图矩阵

本文关键字:3D 视图 Rift Oculus XNA 计算 | 更新日期: 2023-09-27 18:27:48

这是我的相机类

public class Camera
{
    public Matrix View { get; private set; }
    public Matrix Projection { get; private set; }
    public Viewport Viewport { get; private set; }
    public Camera(Viewport viewport, Vector3 position, Vector3 lookAt)
    {
        this.Viewport = viewport;
        this.Update(position, lookAt);
    }
    public void Update(Vector3 position, Vector3 lookAt)
    {
        this.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, this.Viewport.AspectRatio, 1, 500);
        this.View = Matrix.CreateLookAt(position, lookAt, Vector3.Up);
    }
}

我已经为左眼和右眼创建了一个相机。一切都在工作,Oculus在每只眼睛上显示一个单独的图像。问题是Oculus是模糊的,我的大脑无法将两个视图"合并"成一张图像。我试图稍微偏移右眼的图像,但我找不到两只眼睛的正确位置。有人能帮忙吗?

如何在XNA中计算Oculus Rift的3D视图矩阵

两张图像未合并的复视效果与模型视图矩阵无关。模型视图矩阵的分离使两张图像略有不同,从而给人一种深度感,但如果没有分离,通过Oculus的视图理想情况下应该非常像盯着非3D显示器看。

你之所以看到双重效果,是因为你将两个图像集中在每个视口的中心(我分别渲染每个眼睛视图,所以我有一个覆盖左眼的视口,然后是一个覆盖右眼的视口)。如果玩家正前方的视图位于眼睛视图的中心,则观众将始终看到双倍的效果。这是因为每个镜头的中心都不在显示面板一半的中间。相反,它们向中心偏移。

为了在Rift上正确显示内容,您必须考虑此偏移。有很多方法可以做到这一点。最好的方法是改变投影矩阵,使截头体的中心不再直视前方,而是偏向一侧。这是SDK示例中使用的方法。

另一种方法是不使用投影矩阵,而是将每只眼睛的渲染视图向内推向屏幕中心。这不是最佳方法的原因是,这意味着当图像的内部边缘被推到视口外时,您将裁剪图像的部分内部边缘(这实际上不是视图的问题,主要是性能的问题,因为您已经花费了部分性能预算来渲染那些现在裁剪的像素)。这也意味着显示器外缘的部分屏幕根本不会被渲染,这将减少渲染场景的整体视野。

我认为你已经准备好了失真着色器并开始工作,因为如果没有它,你将无法在Oculus Rift中看到正确的会聚图像。

你需要确定你的游戏世界单位对应的真实世界测量单位。这是只有你作为图形引擎的作者才能知道的。游戏世界的物体可以在这里提供线索。假设你的游戏中有汽车,其中一辆是5.0游戏世界单位长。这将是一个指标,即1个游戏世界单位对应于1个现实世界米,因为对于一辆(更大)汽车来说,5米的长度是一个合理的值。

你现在要做的是通过玩家(或你的)IPD(瞳孔间距离)来偏移左视图方向和右视图方向。如SDK文档中所述,人类IPD可以在54毫米到72毫米之间,最常见的值为62毫米。如果1.0世界单位~1米,则1毫米~1.0/1000.0=0.001游戏世界单位。因此,如果IPD为62 mm,则需要将前向视图向量向屏幕中心移动vec3(0.062,0.0,0.0)(左眼)和vec3(-0.062,0.0,0.0%)(右眼)。

注意,您需要对投影矩阵进行另一次移位。您可以通过将投影矩阵乘以偏移矩阵来实现这一点,偏移矩阵将Rift SDK提供的投影偏移作为偏移。这在SDK文档中也有解释。确保矩阵按正确的顺序相乘。;)

这里有一个使用示例代码和示例xna 4.0项目的工作教程(在注释中)

XNA Oculus Rift教程