如何在光线追踪器中使用移动照相机? [英] How to move a camera using in a ray-tracer?
问题描述
我目前正在研究射线追踪技术,我认为我做得很好。但是,我还没有遮盖相机。
I am currently working on ray-tracing techniques and I think I've made a pretty good job; but, I haven't covered camera yet.
直到现在,我仍使用一个平面片段作为视图平面,该片段位于(-width / 2,height / 2,200)
和(宽度/ 2,-高度/ 2,200)
[200只是z的固定数,可以更改]。
Until now, I used a plane fragment for view plane which is located between (-width/2, height/2, 200)
and (width/2, -height/2, 200)
[200 is just a fixed number of z, can be changed].
此外,我主要在 e(0,0,1000)
上使用相机,透视投影。
Addition to that, I use the camera mostly on e(0, 0, 1000)
, and I use a perspective projection.
我将光线从点 e
发送到像素,并在计算出像素颜色后将其打印到图像的相应像素。
I send rays from point e
to pixels, and print it to image's corresponding pixel after calculating the pixel color.
这是我的图片创建。希望您可以通过查看图像来猜测眼睛和视线的位置。
Here is a image I created. Hopefully you can guess where eye and view plane are by looking at the image.
我的问题从这里开始。是时候移动相机了,但是我不知道如何将2D视图平面坐标映射到规范坐标。是否有一个转换矩阵?
My question starts from here. It's time to move my camera around, but I don't know how to map 2D view plane coordinates to the canonical coordinates. Is there a transformation matrix for that?
我认为该方法需要知道视图平面上像素的3D坐标。我不确定这是正确的使用方法。那么,您有什么建议呢?
The method I think requires to know the 3D coordinates of pixels on view plane. I am not sure it's the right method to use. So, what do you suggest?
推荐答案
有多种方法可以做到这一点。这是我的工作:
There are a variety of ways to do it. Here's what I do:
- 选择一个点来表示相机位置(
camera_position
)。 - 选择一个指示摄像机注视方向的向量(
camera_direction
)。 (如果您知道相机正在注视的点,则可以通过从该点减去camera_position
来计算该方向矢量。)您可能希望将其标准化(camera_direction
),在这种情况下,它也是图像平面的法线向量。 - 选择另一个归一化向量,该向量(大约)从相机的角度向上的视图(
camera_up
)。 -
camera_right =交叉(camera_direction,camera_up)
-
camera_up =十字(camera_right,camera_direction)
(这会纠正 up选项中的任何斜率。)
- Choose a point to represent the camera location (
camera_position
). - Choose a vector that indicates the direction the camera is looking (
camera_direction
). (If you know a point the camera is looking at, you can compute this direction vector by subtractingcamera_position
from that point.) You probably want to normalize (camera_direction
), in which case it's also the normal vector of the image plane. - Choose another normalized vector that's (approximately) "up" from the camera's point of view (
camera_up
). camera_right = Cross(camera_direction, camera_up)
camera_up = Cross(camera_right, camera_direction)
(This corrects for any slop in the choice of "up".)
在 camera_position + camera_direction
可视化图像平面的中心。向上和向右的矢量位于图像平面中。
Visualize the "center" of the image plane at camera_position + camera_direction
. The up and right vectors lie in the image plane.
您可以选择图像平面的矩形截面以与屏幕相对应。此矩形部分的宽度或高度与camera_direction的长度之比决定了视野。要放大,可以增加camera_direction或减小宽度和高度。
You can choose a rectangular section of the image plane to correspond to your screen. The ratio of the width or height of this rectangular section to the length of camera_direction determines the field of view. To zoom in you can increase camera_direction or decrease the width and height. Do the opposite to zoom out.
因此,给定像素位置(i,j)
,您需要<图像平面上该像素的code>(x,y,z)。从中可以减去 camera_position
来获得射线矢量(然后需要对其进行归一化)。
So given a pixel position (i, j)
, you want the (x, y, z)
of that pixel on the image plane. From that you can subtract camera_position
to get a ray vector (which then needs to be normalized).
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);
}
这只是为了说明,因此未进行优化。
This is meant to be illustrative, so it is not optimized.
这篇关于如何在光线追踪器中使用移动照相机?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!