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

hev*_*ele 5 c++ camera raytracing transformation

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

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

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

我将光线从点发送e到像素,并在计算像素颜色后将其打印到图像的相应像素.在此输入图像描述

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

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

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

Adr*_*thy 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) (这可以纠正选择"向上"的任何污点.)

可视化图像平面的"中心" 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);
}
Run Code Online (Sandbox Code Playgroud)

这是说明性的,因此没有进行优化.