2

因此,我决定重写一个用 C++ 编写的旧光线追踪器,并利用 XNA 框架在 C# 中完成。

我仍然有我的旧书并且可以按照笔记进行操作,但是我对一些想法感到困惑,我想知道是否有人可以很好地表达出来。


    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(在模型空间中)

因此,这是有道理的

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

我还记得一些关于视图矩阵如何被转置和倒置的事情,因为它是正交的。

4

2 回答 2

0

真的没有必要使用矩阵来进行光线追踪。透视投影只是脱离了系统。这是光线追踪的好处之一。

你的评论也很混乱。

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

NDC 在光线追踪中没有任何作用,所以我不知道你在说什么。您对 u, v 代码所做的所有事情都是根据您在世界空间中设置的虚拟像素网格计算光线的方向。然后你将把光线追踪到场景中,看看它是否与任何东西相交。

真的,你现在真的不需要担心不同的空间仪式。只需将所有内容放入世界坐标中即可。如果你想做复杂的模型(模型变换,比如缩放旋转和拉屎),可能需要模型->世界变换,但是当你第一次开始编写光线追踪器时,你不需要担心这些东西。

如果您想使用 XNA,您可以使用该相机类,但就像某些成员将无用一样。即矩阵和近平面和远平面。

于 2011-07-27T19:14:54.213 回答
0

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

  1. 您想将像素 X&Y 转换为从 -1 到 1 的统一矩形(基本上将相机居中在查看框架内)
  2. 执行逆投影矩阵,使用 FOV、纵横比和近平面将像素(在 NDC 坐标中)放置到世界空间坐标中
  3. 执行相机矩阵的逆运算以将相对于相机的坐标放置在世界空间中
  4. 计算方向
于 2011-07-29T15:07:34.477 回答