关于使用XNA进行光线跟踪的世界视图投影矩阵问题

时间:2011-07-27 18:31:49

标签: xna matrix-multiplication raytracing coordinate-systems perspectivecamera

所以我决定重写一个用C ++编写的老式光线跟踪器,用C#编写,利用XNA框架。

我仍然有我的旧书并且可以按照说明操作然而我对一些想法感到困惑,我想知道是否有人可以很好地表达它。


    for each x pixel do
        for each y pixel do
        //Generate Ray
        //1 - Calculate world coordinates of current pixel
           //1.1 Calculate Normalized Device coordinates for current pixel 1- to -1 (u, v) 
           u = (2*x/ WIDTH) - 1 ;
           v = (2*y/HEIGHT) - 1 ;
           Vector3 rayDirection = -1*focalLength + u'*u + v'*v


在上面的代码中,u'和v'是针对给定摄像机计算的正交基础(我知道相同的名称会让人感到困惑)

如果我按照书中所表达的方式进行操作,那就有效。但是我试图利用XNA并对如何使用矩阵执行相同的操作感到困惑。

所以我尝试用XNA代码替换以下步骤


    class Camera
        {
           public Camera(float width, float height)
           {
            AspectRatio = width/height;
            FOV = Math.PI / 2.0f;
            NearPlane = 1.0f;
            FarPlane = 100.0f;
            ViewMatrix = Matrix.CreateLookAt(Position, Direction,this.Up);
            ProjectionMatrix=Matrix.CreatePerspectiveFieldOfView(FOV,
                                              AspectRatio,NearPlane,FarPlane); 
           }
        }

在这一点上,为了得到任何像素(x,y)的方向向量,我应该按照操作的顺序混淆?

在我脑海里,我在想: (u,v)= ProjectionMatrix * ViewMatrix * ModelToWorld * Vertex(在模型空间中)

因此

是有意义的

顶点(在世界空间中)=反向(ViewMatrix)*反向(ProjectionMatrix)* [u,v,0]

我还记得一些关于视图矩阵如何被转置以及倒置的东西,因为它是正交的。

2 个答案:

答案 0 :(得分:0)

Theres确实无需使用矩阵进行光线追踪。透视投影刚刚脱离系统。这是光线追踪的好处之一。

你的评论也令人困惑。

// 1 - 计算当前像素的世界坐标            //1.1计算当前像素1到-1(u,v)的标准化设备坐标

NDC在光线追踪中没有任何作用,所以我不知道你在这里谈论什么。所有你正在做的事情,你的代码是计算方向 对于基于您在世界空间中设置的虚拟像素网格的光线。然后你将跟踪光线进入场景并查看它是否相交 什么都有。

真的,你现在真的不需要担心不同的空间仪式。只需将所有内容都放入世界坐标并称之为一天。如果你想做 复杂的模型(模型转换,如缩放旋转和狗屎)可能需要模型 - >世界变换,但是当你第一次开始写一条光线 跟踪器你不需要担心那些东西。

如果你想使用XNA,你可以使用那个相机类,但是像一些成员将会毫无用处。即matricies和近远平面。

答案 1 :(得分:0)

NDC的原因是您可以将图像高度/宽度(以像素为单位)映射到任意大小的图像(不一定是1:1) 基本上我理解的是以下内容:

  1. 您希望将像素X和Y转换为-1到1的均匀矩形(基本上将相机置于查看框架内)
  2. 执行反投影矩阵,使用FOV,纵横比和近平面将像素(在NDC坐标中)放入世界空间坐标
  3. 执行相机矩阵的反转,以将相对于相机的坐标放在世界空间中
  4. 计算方向