views:

97

answers:

1

I'm writing a ray tracer (using left-handed coordinates, if that makes a difference). It's for the sake of teaching myself the principles, so I'm not using OpenGL or complex features like depth of field (yet). My camera can have an arbitrary position and orientation; I indicate them by way of three vectors, location, look_at, and sky, which behave like the equivalent POV-Ray vectors. Its "film" also has a width and height. (The focal length is implied by the distance from position to look_at.)

My problem is that don't know how to cast the rays. I have two quantities, vx and vy, that indicate where the ray should end up. They both vary from -1 to 1. If they're both -1, I'm casting the ray from the camera's position to the top-left corner of the "film"; if they're both 1, the bottom-right; if they're both 0, the center; and the rest is apparent.

I'm not familiar enough with vector arithmetic to derive an equation for the ray. I would appreciate an explanation of how to do so.

+1  A: 

You've described what needs to be done quite well already. Your field of view is determined by the distance between your camera and your "film" that you're going to cast your rays through. The further away the camera is from the film, the narrower your field of view is.

Imagine the film as a bitmap image that the camera is pointing to. Say we position the camera one unit away from the bitmap. We then have to cast a ray though each of the bitmap's pixels.

The vector is extremely simple. If we put the camera location to (0,0,0), and the bitmap film right in front of it with it's center at (0,0,1), then the ray to the bottom right is - tada - (1,1,1), and the one to the bottom left is (-1,1,1).

That means that the difference between the bottom right and the bottom left is (2,0,0).

Assume that your horizontal bitmap resolution should be 1000, then you can iterate through the bottom line pixels as follows:

width = 1000;
cameraToBottomLeft = (-1,1,1);
bottomLeftToBottomRight = (2,0,0);

for (x = 0; x < width; x++) {
    ray = cameraToBottomLeft + (x/width) * bottomLeftToBottomRight;
    ...
}

If that's clear, then you just add an equivalent outer loop for your lines, and you have all the rays that you will need.

You can then add appropriate variables for the distance of the camera to the film and horizontal and vertical resolution. When that's done, you could start changing your look vector and your up vector with matrix transformations.

If you want to wrap your head around computer graphics, an introductory textbook could be of great help. I used this one in college, and I think I liked it.

Henning
Thanks, I got it to work now.
Remy