我目前正在研究光线追踪技术,我认为我做得很好;但是,我还没有覆盖相机。
到目前为止,我使用了一个位于 (-width/2, height/2, 200)
和 (width/2, -height/2) 之间的平面片段作为 View 平面, 200)
[200只是固定的z个数,可以改变]。
除此之外,我主要在 e(0, 0, 1000)
上使用相机,并且使用透视投影。
我从点e
发送光线到像素,并在计算像素颜色后将其打印到图像的相应像素。
这是我创建的图像。希望您可以通过查看图像猜出眼睛和 View 平面的位置。
我的问题从这里开始。是时候四处移动我的相机了,但我不知道如何将 2D View 平面坐标映射到规范坐标。是否有一个转换矩阵?
我认为该方法需要知道 View 平面上像素的 3D 坐标。我不确定这是正确的使用方法。那么,您有什么建议?
最佳答案
有多种方法可以做到这一点。这是我的做法:
- 选择一个点来表示相机位置 (
camera_position
)。 - 选择一个 vector 来指示相机的观察方向 (
camera_direction
)。 (如果你知道相机正在注视的一个点,你可以通过从那个点减去camera_position
来计算这个方向 vector 。)你可能想要归一化(camera_direction
),在在这种情况下,它也是图像平面的法 vector 。 - 选择另一个从相机的角度(
camera_up
)(大约)“向上”的归一化 vector 。 camera_right = Cross(camera_direction, camera_up)
camera_up = Cross(camera_right, camera_direction)
(这纠正了“向上”选择中的任何倾斜。)
在 camera_position + camera_direction
处可视化图像平面的“中心”。向上和向右 vector 位于图像平面内。
您可以选择图像平面的矩形部分来对应您的屏幕。此矩形部分的宽度或高度与 camera_direction 的长度之比决定了视野。要放大,您可以增加 camera_direction 或减小宽度和高度。执行相反的操作以缩小。
因此给定一个像素位置 (i, j)
,您需要该像素在图像平面上的 (x, y, z)
。您可以从中减去 camera_position
以获得光线 vector (然后需要对其进行归一化)。
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);
}
这只是说明性的,因此并未优化。
关于c++ - 如何在光线追踪器中移动相机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13078243/