我目前正在研究光线追踪技术,我认为我已经做得相当不错了;但是,我还没有讨论过相机。
到目前为止,我使用平面片段作为视图平面,它位于(-width/2, height/2, 200)
and (width/2, -height/2, 200)
[200只是z的固定数字,可以改变]。
除此之外,我主要使用相机e(0, 0, 1000)
,我使用透视投影。
I send rays from point e
to pixels, and print it to image's corresponding pixel after calculating the pixel color.
这是我创建的图像。希望您可以通过查看图像来猜测眼睛和视平面的位置。
我的问题从这里开始。是时候移动我的相机了,但我不知道如何将 2D 视图平面坐标映射到规范坐标。有一个变换矩阵吗?
我认为该方法需要知道视图平面上像素的 3D 坐标。我不确定这是正确的使用方法。所以你有什么建议?
有多种方法可以做到这一点。这就是我所做的:
- 选择一个点来表示相机位置(
camera_position
).
- 选择一个指示相机观察方向的矢量(
camera_direction
)。 (如果您知道相机正在观察的点,您可以通过减去来计算该方向向量camera_position
从那时起。)您可能想要标准化(camera_direction
),在这种情况下它也是图像平面的法线向量。
- 选择另一个从相机的角度(大约)“向上”的归一化向量(
camera_up
).
camera_right = Cross(camera_direction, camera_up)
-
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);
}
这只是为了说明,因此并未进行优化。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)