# How to calculate ray

In ray-tracing technique critical point is to calculate rays which came out from eye $$E$$ to target $$T$$ through pixel $$P_{ij}$$ on viewport. The "viewport" is represented as rectangle divided to square pixels - this rectangle is perpendicular to line which go through points $$E$$, $$C$$ (viewport center) and $$T$$. The ray (red line on image) is represented by point $$E$$ and unit vector $$r_{ij}$$ (not shown in picture but it lay on red line) - below is picture which show "geometry" - but what are the formulas to calculate $$r_{ij}$$?

The given input values are:

• eye position $$E$$,
• target position $$T$$,
• field of view $$\theta$$ (angle, for human eye $$\approx 90^\circ$$),
• number of square pixels $$k$$ (horizontal direction) and $$m$$ (vertical direction).
• we also know vertical $$w$$ vector usually equal to $$w=[wx,wy,wz]=[0,1,0]$$ (not shown on picture) which indicate where is up and where is down

The orthogonal vectors $$v$$ and $$b$$ (and $$t$$) on picture are determined by $$w$$ and $$t=T-E$$ and maybe will useful in $$r_{ij}$$ calculations. The $$d$$ and pixel size is arbitrary and don't change the result because of fixed $$\theta$$.

Question: How to calculate unit vector $$r_{ij}$$ knowing input values described above?

• What exactly is it that you want to know? – amd Jan 16 at 0:48
• @amd I update question - now it is more clear? – Kamil Kiełczewski Jan 16 at 6:08
• This is described in almost all tutorials and books on the subject. – lightxbulb Jan 16 at 6:45
• @lightxbulb In all sources that I know - there are similar description to above, but no explicite formulas – Kamil Kiełczewski Jan 16 at 6:55
• Scratchapixel, pbrt-book, ray tracing in one weekend are all free access, and all of those explain how this is done. – lightxbulb Jan 16 at 7:29

IDEA: lets find position of center of each pixel $$P_{ij}$$ which allows us to easily find ray which starts at $$E$$ and go thought that pixel. To do it we find first $$P_{1m}$$ and find others by move on vievports plane.

ASSUMPTION: Below we introduce formulas which includes distance $$d$$ between eye and viewport however this value will be reduced during ray $$r_{ij}$$ normalization (so you might as well accept that $$d=1$$ and remove it from calculations).

PRECALCULATIONS: First we calculate normalized vectors $$v_n, b_n$$ from picutre (which are parallel to viewport plane and give as direction for shifting)

$$t = T-E, \qquad b = w\times t$$

$$t_n = \frac{t}{||t||}, \qquad b_n = \frac{b}{||b||}, \qquad v_n = t_n\times b_n \\$$

notice: $$C=E+t_nd$$, then we calculate viewport size divided by 2 and including aspect ratio $$\frac{m}{k}$$

$$g_x=\frac{h_x}{2} =d \tan \frac{\theta}{2}, \qquad g_y =\frac{h_y}{2} = g_x \frac{m}{k}$$

and then we calculate shifting vectors $$q_x,q_y$$ on viewport $$x,y$$ direction and viewport left upper pixel

$$q_x = \frac{2g_x}{k-1}b_n, \qquad q_y = \frac{2g_y}{m-1}v_n, \qquad p_{1m} = t_n d - g_xb_n - g_yv_n$$

CALCULATIONS: notice that $$P_{ij} = E + p_{ij}$$ and ray $$R_{ij} = P_{ij} -E = p_{ij}$$ so normalized ray $$r_{ij}$$ is

$$p_{ij} = p_{1m} + q_x(i-1) + q_y(j-1)$$ $$r_{ij} = \frac{p_{ij}}{||p_{ij}||}$$

TEST: above formulas wast tested here (works in browser)

SUMMARY: The above form is convenient to use it in shaders where in shader kernel we perform only final calculation based on prcarculated $$q_x,q_y$$ and $$p_{1m}$$. Wiki here.