如何使用光线追踪器移动相机?

时间:2012-10-25 22:22:24

标签: c++ camera transformation raytracing

我目前正致力于射线追踪技术,我认为我做得很好;但是,我还没有覆盖相机。

到目前为止,我使用了位于(-width/2, height/2, 200)(width/2, -height/2, 200)之间的视平面的平面片段[200只是固定数量的z,可以更改]。

除此之外,我主要在e(0, 0, 1000)上使用相机,并使用透视投影。

我将点e的光线发送到像素,并在计算像素颜色后将其打印到图像的相应像素。enter image description here

这是我创建的图片。希望您可以通过查看图像来猜测眼睛和视平面的位置。

我的问题从这里开始。是时候移动我的相机,但我不知道如何将2D视图平面坐标映射到规范坐标。那有变换矩阵吗?

我认为该方法需要知道视平面上像素的3D坐标。我不确定这是正确的使用方法。所以,你有什么建议?

2 个答案:

答案 0 :(得分:13)

有多种方法可以做到这一点。这是我的所作所为:

  1. 选择一个代表相机位置的点(camera_position)。
  2. 选择一个矢量,指示相机的方向(camera_direction)。 (如果您知道相机正在观察的一个点,您可以通过从该点减去camera_position来计算此方向向量。)您可能想要标准化(camera_direction),在这种情况下它也是正常的矢量图像平面。
  3. 从相机的角度(camera_up)选择另一个(近似)“向上”的标准化矢量。
  4. camera_right = Cross(camera_direction, camera_up)
  5. camera_up = Cross(camera_right, camera_direction)(这可以纠正选择“up”中的任何污点。)
  6. camera_position + camera_direction处可视化图像平面的“中心”。向上和向右矢量位于图像平面中。

    您可以选择图像平面的矩形部分以对应您的屏幕。该矩形截面的宽度或高度与camera_direction的长度之比决定了视场。要放大,您可以增加camera_direction或减小宽度和高度。做相反的事情来缩小。

    因此,给定像素位置(i, j),您需要图像平面上该像素的(x, y, z)。从那里你可以减去camera_position来得到一个射线矢量(然后需要进行标准化)。

    Ray ComputeCameraRay(int i, int j) {
      const float width = 512.0;  // pixels across
      const float height = 512.0;  // pixels high
      double normalized_i = (i / width) - 0.5;
      double normalized_j = (j / height) - 0.5;
      Vector3 image_point = normalized_i * camera_right +
                            normalized_j * camera_up +
                            camera_position + camera_direction;
      Vector3 ray_direction = image_point - camera_position;
      return Ray(camera_position, ray_direction);
    }
    

    这是说明性的,因此未进行优化。

答案 1 :(得分:2)

对于光栅化渲染器,您往往需要一个变换矩阵,因为这是您如何直接从3D坐标映射到屏幕2D坐标。

对于光线追踪,没有必要,因为您通常从2D空间中的已知像素坐标开始

考虑到眼睛的位置,屏幕中心的3个空间中的一个点,以及" up"并且"对",它很容易计算3D" ray"从眼睛位置到指定像素。

我之前在https://stackoverflow.com/a/12892966/6782

发布了我自己的光线追踪器的一些示例代码