# Perspective Raytracing

Given the up and focal vector of the perspective camera, the position of the camera and the vertical and horizontal opening angle of the FOV. How can I calculate a ray for given screen space coordinates (x, y) where x, y are between -1 and 1 (inclusive). I tried this:

1) Calculate the vectors sx, sy that span the image plane

sy = -norm(up)

sx = norm(cross(focal, sy))

2) Calculate the focal length f

f = 1 * sin(90 - vertical) / sin(vertical)

3) Create the ray

dir = (center + x * sx + y * sy + f * forward) - center

r(t) = center + t * norm(dir)

But the resulting image does not turn out like the reference image. Someone know what I am doing wrong?

• sin most likely accepts radians. Also you can cancel out the +center-center: dir = x * sx + y * sy + f * forward. I am unsure why you calculate the focal length like this either. Oct 27, 2019 at 21:58
• Oh yes in my code i have pi/2 not 90, but what do you mean with the focal length? Oct 27, 2019 at 22:16

Let the horizontal FOV be given as theta (in radians), and the vertical FOV be given as phi (in radians). The we know that:

$$\tan\frac{\theta}{2}=\frac{w}{f}, \tan\frac{\phi}{2}=\frac{h}{f}$$

Let us pick $$f = 1$$, then $$w = \tan\frac{\theta}{2}, h = \tan\frac{\phi}{2}$$. Now your ray generation direction generation formula looks like:

$$\pmb{d} = x w\pmb{u} + yh\pmb{v} + \pmb{w}$$

Where $$\pmb{u},\pmb{v}, \pmb{w}$$ are your sx,sy, forward vectors. Essentially, I found the extent of the smallest/largest x and y respectively ($$1w = w, -1w=-w$$, etc.). You can premultiply $$\pmb{u}, \pmb{v}$$ with $$w, h$$ respectively, if you don't want to perform the multiplication per ray.

• hm I am still having trouble recreating the last reference image provided for this task. this is how I am doing my ray now, but that doesnt seem to work for the last image ( probably missing something ): sx=norm(cross(forward, up)) * tan(horizontal/2), sy=norm(cross(forward, sx)) * tan(vertical/2) ( up may not be orthogonal to forward ), r(t)=origin + t * norm(x*sx + y*sy + forward). Am I missing something? Oct 30, 2019 at 14:53
• @Yamahari Looks correct. Maybe your fov us given in half angles? Then remove the /2. Also is forward normalized? Oct 30, 2019 at 16:35
• i doubt the angle is only half, for the last image the given vertical/horizontal angles are pi * 0.9. Yes the forward vector is normalized Oct 30, 2019 at 17:14
• @Yamahari Then all should be fine, there is probably a different reason you do not get the reference. Oct 30, 2019 at 17:24
• oh man I just found out what happened, I was too stupid to use c++ correctly xD thx Oct 30, 2019 at 17:42