<p>First, the viewport size:
<span class="math-container">$$h_x = 2*d*tan(\theta_x/2)$$</span>
<span class="math-container">$$h_y = 2*d*tan(\theta_y/2)$$</span></p>

<p>Each pixel (from your diagram) has the following size in the eye coordinate system:
<span class="math-container">$$W = h_x / (k-1)$$</span>
<span class="math-container">$$H = h_y / (m-1)$$</span></p>

<p>Note that usually the field of view encompasses whole pixels and doesn't stop at the center of the edge pixels like your diagram shows.</p>

<p>If <span class="math-container">$P_c$</span> is the viewport center in pixel coordinates, let:</p>

<p><span class="math-container">$$\vec {P'_{ij}} = P_{ij} - P_c$$</span></p>

<p>Therefore, <span class="math-container">$P_{ij}$</span> in eye space becomes:
<span class="math-container">$$
[P_{ij}]_e =
    \begin{pmatrix}
    (W, 0) * \vec {P'_{ij}} \\
    (0, H) * \vec {P'_{ij}} \\
    d \\
    \end{pmatrix}
$$</span></p>

<p>and in the standard base:
<span class="math-container">$$[P_{ij}]_{std} = (\vec b, \vec v, \vec t) * [P_{ij}]_e$$</span></p>

<p>Normalize the one in the base you want to get <span class="math-container">$r_{ij}$</span>.</p>

<h1>Original answer</h1>

<p>The last time I wanted to go from window coordinates (pixels) to eye coordinates, I followed the steps outlined here in the <a href="https://www.khronos.org/opengl/wiki/Compute_eye_space_from_window_space" rel="nofollow noreferrer">OpenGL wiki</a>. Once you have the eye coordinates, you can just normalize the vector to obtain <span class="math-container">$r_{ij}$</span>.</p>

CC BY-SA 4.0
2019-01-18T09:54:14.253Z
The *eye position* is known, but not the *pixel's position in the eye coordinate system* which is what you're looking for.
bernie
CC BY-SA 4.0
2019-01-18T09:59:57.370Z
ok but the problem is that I not use OpenGL explicity and don't have that stuff described in wiki likes clip space, projection matrix etc. :( I have only simplified javascript used by [gpu.js](https://github.com/gpujs/gpu.js) library which allows me to perform any calculations on gpu - the kernel function (fragment shader written in simplidied javascript) takes on input i,j as this.thread.x and this.thread.y coordinates and thats all (plus input parameters which I describe on question).
Kamil Kiełczewski
CC BY-SA 4.0
2019-01-18T12:36:54.237Z
Can you explain what is the meaning of $(W, 0) * \vec {P'_{ij}}$ and $[P_{ij}]_e$ and $(\vec b, \vec v, \vec t)$ and $[P_{ij}]_{std}$ (and how to get $r_{ij}$ from it) because I don't understand notation
Kamil Kiełczewski
CC BY-SA 4.0
2019-01-18T13:24:57.093Z
Sorry that's just too much to explain. $(W, 0) * \vec {P'_{ij}}$ means multiply the x component of $\vec {P'_{ij}}$ by W. Read up on linear algebra and change of basis for more information. Also, you did not specify in which basis you want $r_[ij]$.
bernie
CC BY-SA 4.0
2019-01-18T13:40:21.050Z
you not explain meaning of all symbols - sorry I dont understant. I dont indroduce any basis - because I need result in natural/canonical basis $\left[\begin{matrix} 1 &0 &0 \\ 0 &1 &0 \\ 0 &0 &1\end{matrix}\right]$ - which means that $E, T, w$ and $r_{ij}$ shoud not be transformed to any basis
Kamil Kiełczewski
CC BY-SA 4.0
2019-01-18T13:47:29.747Z
you also not provide formula for viewport center $C=P_c$ which you use in your calculations
Kamil Kiełczewski
CC BY-SA 4.0
2019-01-18T07:13:57.957Z
2019-01-18T12:23:05.723Z
2019-01-18T12:23:05.723Z
bernie
<h2>GPU friendly - full formulas</h2>
<p><strong>IDEA</strong>: lets find position of center of each pixel <span class="math-container">$P_{ij}$</span> which allows us to easily find ray which starts at <span class="math-container">$E$</span> and go thought that pixel. To do it we find first <span class="math-container">$P_{1m}$</span> and find others by move on vievports plane.</p>
<p><strong>ASSUMPTION</strong>: Below we introduce formulas which includes distance <span class="math-container">$d$</span> between eye and viewport however this value will be reduced during ray <span class="math-container">$r_{ij}$</span> normalization (so you might as well accept that <span class="math-container">$d=1$</span> and remove it from calculations).</p>
<p><strong>PRECALCULATIONS</strong>: First we calculate normalized vectors <span class="math-container">$v_n, b_n$</span> from picutre (which are parallel to viewport plane and give as direction for shifting)</p>
<p><span class="math-container">$$t = T-E, \qquad b = w\times t  $$</span></p>
<p><span class="math-container">$$ 
t_n = \frac{t}{||t||}, \qquad
b_n = \frac{b}{||b||}, \qquad
v_n = t_n\times b_n \\ 
$$</span></p>
<p>notice: <span class="math-container">$C=E+t_nd$</span>, then we calculate viewport size divided by 2 and including aspect ratio <span class="math-container">$\frac{m}{k}$</span></p>
<p><span class="math-container">$$g_x=\frac{h_x}{2} =d \tan \frac{\theta}{2}, \qquad  g_y =\frac{h_y}{2} = g_x \frac{m}{k}$$</span></p>
<p>and then we calculate shifting vectors <span class="math-container">$q_x,q_y$</span> on viewport <span class="math-container">$x,y$</span> direction and viewport left upper pixel</p>
<p><span class="math-container">$$ 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$$</span></p>
<p><strong>CALCULATIONS</strong>: notice that <span class="math-container">$P_{ij} = E + p_{ij}$</span> and ray <span class="math-container">$R_{ij} = P_{ij} -E = p_{ij}$</span> so normalized ray <span class="math-container">$r_{ij}$</span> is</p>
<p><span class="math-container">$$ p_{ij} = p_{1m} + q_x(i-1) + q_y(j-1)$$</span>
<span class="math-container">$$ r_{ij} = \frac{p_{ij}}{||p_{ij}||} $$</span></p>
<p><strong>TEST</strong>: above formulas wast tested <a href="https://kamil-kielczewski.github.io/fractals/mandelbulb.html" rel="nofollow noreferrer">HERE</a> (works in browser)</p>
<p><strong>SUMMARY</strong>: The above form is convenient to use it in shaders where in shader kernel we perform only final calculation based on prcarculated <span class="math-container">$q_x,q_y$</span> and <span class="math-container">$p_{1m}$</span>. Wiki <a href="https://en.wikipedia.org/wiki/Ray_tracing_(graphics)#Calculate_rays_for_rectangular_viewport" rel="nofollow noreferrer">here</a>.</p>

CC BY-SA 4.0
2019-01-21T12:37:59.227Z
2021-03-16T19:28:58.373Z
2021-03-16T19:28:58.373Z
Kamil Kiełczewski
<p>Read up on the basics for ray-tracing <a href="http://www.scratchapixel.com/index.php?redirect" rel="nofollow noreferrer">here</a>,</p>
<p>Usually we don't mess up with viewports and stuff in raytracing, So I'm just telling you for the case where viewport equals the Image Width and Height.</p>
<p>There are two cases when the field of view changes. Either you move the image plane back and forth or you increase the size. We choose to change <span class="math-container">$d$</span> ( former approach).</p>
<p>Calculating ray is simple when the camera is aligned with the world, all you have to do is</p>
<p><span class="math-container">$d = 1/tan(\theta_{fov}/2))$</span></p>
<p><span class="math-container">$P_x = P_x + 0.5$</span><br />
<span class="math-container">$P_y = P_y + 0.5$</span></p>
<p><span class="math-container">$aspect\_ratio = width/height$</span></p>
<p><span class="math-container">$ray.dir.x = aspect\_ratio *(2*P_x/width) -1$</span></p>
<p><span class="math-container">$ray.dir.y = (2*P_y/height) - 1$</span></p>
<p><span class="math-container">$ray.dir.z = d$</span></p>
<p>The <span class="math-container">$Z$</span> coordinate should be negative or positive depending on whether you are using a right handed or left handed coordinate system. <span class="math-container">$P_x$</span> and <span class="math-container">$P_y$</span> are pixel coordinates offset by <span class="math-container">$0.5$</span> to get the center of the pixel.</p>
<p>The process is simple. You first map your image to NDC space (-1, 1). However to account for non-square images we scale the <span class="math-container">$X$</span> coordinate by Aspect ratio so it's <span class="math-container">$[-a, a]$</span> in <span class="math-container">$X$</span> and <span class="math-container">$[-1,1]$</span> in Y. The ray's direction through the pixel is then given by above formulas. You might have to flip the <span class="math-container">$Y$</span> coordinate if the image coordinate's origin is top left instead of bottom left.</p>
<p>Note however the link bases all their coordinate systems and space names on RenderMan which is quite different from OpenGL. For camera that isn't aligned with the world coordinate you have to multiply by the transformation matrix as described by bernie in his answer</p>
<p>EDIT:-</p>
<p>First of all let's clear up on -ve and +ve <span class="math-container">$d$</span>. For right handed coordinate systems you always set <span class="math-container">$ray.dir.z = -d$</span> and for left handed <span class="math-container">$ray.dir.z = d$</span> This is because in camera space there is no concept of half rays having -ve Z and half +ve, that happens in world space. When you multiply by the transformation matrix it takes care of these cases for you since the transformation matrix is designed keeping in mind whether you are working on a left handed or right handed system. I know i said that you always set it to +ve <span class="math-container">$d$</span> but i was wrong in the comments, sorry.</p>
<p>Now coming to your other question. You need the vectors <span class="math-container">$b,v,t$</span> and <span class="math-container">$E$</span> for creating a transformation matrix. Usually in raytracing you create your camera and initialize its transformation matrix to the standard case (aligned with world space) Then when you move your mouse or something you create a respective rotation matrix and transform the original camera matrix to keep up with these changes. Then when calculating the ray you multiply it as I said above to get ray direction easily. So you probably need to manage your own Camera first.</p>
<p>Since you aren't managing in this case you explicitly need to find these vectors. You mention you have the <span class="math-container">$w$</span> vector which is global up. <span class="math-container">$t$</span> is easy to find as you say</p>
<p><span class="math-container">$t = T-E$</span></p>
<p>However remember this is the viewing direction not the basis vector. For right handed coordinate systems, the basis vector for <span class="math-container">$Z$</span> is <span class="math-container">$-V_{dir}$</span></p>
<p>For <span class="math-container">$b$</span> which is Camera's right vector. You do,
<span class="math-container">$ w \times t = b$</span></p>
<p>This gets you the Camera's up vector. Then you do,</p>
<p><span class="math-container">$ t \times b = v$</span></p>
<p>to get the Camera's up vector. This works as long as <span class="math-container">$t$</span> doesn't equal <span class="math-container">$w$</span> which is the global up.</p>
<p>So after you have these you can create a camera transformation matrix with <span class="math-container">$c_1, c_2, c_3, c_4 = b, v, t, E$</span> respectively.</p>
<p>EDIT2:-
Instead of following above approach you can also do Gram-Schmidt orthogonalization which is more standard in this case. Using this you get the Camera's up vector <span class="math-container">$v$</span> as</p>
<p><span class="math-container">$v = w - (t.w)\hat{t}$</span></p>
<p>Then side vector as,</p>
<p><span class="math-container">$b = v \times t$</span></p>
<p>For right handed systems. For left handed systems you need to change the ordering of cross products.</p>

CC BY-SA 4.0
2019-01-21T11:32:37.837Z
Yes. you can see my open-source path tracer as a reference. It contains the createRay function.

https://github.com/gallickgunner/Yune/blob/master/Yune-1.x/progressive-PT.cl
gallickgunner
CC BY-SA 4.0
2019-01-18T15:45:39.420Z
2019-01-21T11:18:34.597Z
2020-06-18T08:32:12.800Z
gallickgunner
<p>In <a href="https://en.wikipedia.org/wiki/Ray_tracing_(graphics)" rel="nofollow noreferrer">ray-tracing</a> technique critical point is to calculate rays which came out from eye <span class="math-container">$E$</span> to target <span class="math-container">$T$</span> through pixel <span class="math-container">$P_{ij}$</span> on viewport. The "viewport" is represented as rectangle divided to square pixels - this rectangle is perpendicular to line which go through points <span class="math-container">$E$</span>, <span class="math-container">$C$</span> (viewport center) and <span class="math-container">$T$</span>. The ray (red line on image) is represented by point <span class="math-container">$E$</span> and unit  vector <span class="math-container">$r_{ij}$</span> (not shown in picture but it lay on red line) - below is picture which show "geometry" - but what are the formulas to calculate <span class="math-container">$r_{ij}$</span>? </p>

<p>The given input values are: </p>

<ul>
<li>eye position <span class="math-container">$E$</span>, </li>
<li>target position <span class="math-container">$T$</span>, </li>
<li>field of view <span class="math-container">$\theta$</span> (angle, for human eye <span class="math-container">$\approx 90^\circ$</span>), </li>
<li>number of square pixels <span class="math-container">$k$</span> (horizontal direction) and <span class="math-container">$m$</span> (vertical direction).</li>
<li><span class="math-container">$i,j$</span> processed pixel indexes where <span class="math-container">$1\leq i\leq k$</span> and <span class="math-container">$1\leq j\leq m$</span>   </li>
<li>we also know vertical <span class="math-container">$w$</span> vector usually equal to <span class="math-container">$w=[wx,wy,wz]=[0,1,0]$</span> (not shown on picture) which indicate where is up and where is down </li>
</ul>

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

<p><strong>Question</strong>: How to calculate unit vector <span class="math-container">$r_{ij}$</span> knowing input values described above?</p>

<p><a href="https://i.sstatic.net/aUdHD.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/aUdHD.png" alt="enter image description here"></a></p>

CC BY-SA 4.0
2023-08-27T09:23:14.167Z
What kind of program did you use to render this graphic?
Tooster
CC BY-SA 4.0
2023-08-27T20:39:07.603Z
@Tooster latex PGF/TikZ
Kamil Kiełczewski
<raytracing><mathematics><linear-algebra><ray>
How to calculate ray
Kamil Kiełczewski
# How to calculate ray

(Asked by: username_0 on 2019-01-16)

In [ray-tracing](https://en.wikipedia.org/wiki/Ray_tracing_(graphics)) 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).
* $i,j$ processed pixel indexes where $1\leq i\leq k$ and $1\leq j\leq m$
* 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?

[![enter image description here](https://i.sstatic.net/aUdHD.png)](https://i.sstatic.net/aUdHD.png)

**Tags:** raytracing, mathematics, linear-algebra, ray

> **Comments:**
> **username_1**: What kind of program did you use to render this graphic?  
> **username_0**: @username_1 latex PGF/TikZ  

---

## 3 answers

### Answer by username_3 on 2019-01-18. Score: 6 | Accepted answer

Read up on the basics for ray-tracing [here](http://www.scratchapixel.com/index.php?redirect),

Usually we don't mess up with viewports and stuff in raytracing, So I'm just telling you for the case where viewport equals the Image Width and Height.

There are two cases when the field of view changes. Either you move the image plane back and forth or you increase the size. We choose to change $d$ ( former approach).

Calculating ray is simple when the camera is aligned with the world, all you have to do is

$d = 1/tan(\theta\_{fov}/2))$

$P\_x = P\_x + 0.5$  
$P\_y = P\_y + 0.5$

$aspect\\_ratio = width/height$

$ray.dir.x = aspect\\_ratio \*(2\*P\_x/width) -1$

$ray.dir.y = (2\*P\_y/height) - 1$

$ray.dir.z = d$

The $Z$ coordinate should be negative or positive depending on whether you are using a right handed or left handed coordinate system. $P\_x$ and $P\_y$ are pixel coordinates offset by $0.5$ to get the center of the pixel.

The process is simple. You first map your image to NDC space (-1, 1). However to account for non-square images we scale the $X$ coordinate by Aspect ratio so it's $[-a, a]$ in $X$ and $[-1,1]$ in Y. The ray's direction through the pixel is then given by above formulas. You might have to flip the $Y$ coordinate if the image coordinate's origin is top left instead of bottom left.

Note however the link bases all their coordinate systems and space names on RenderMan which is quite different from OpenGL. For camera that isn't aligned with the world coordinate you have to multiply by the transformation matrix as described by username_2 in his answer

EDIT:-

First of all let's clear up on -ve and +ve $d$. For right handed coordinate systems you always set $ray.dir.z = -d$ and for left handed $ray.dir.z = d$ This is because in camera space there is no concept of half rays having -ve Z and half +ve, that happens in world space. When you multiply by the transformation matrix it takes care of these cases for you since the transformation matrix is designed keeping in mind whether you are working on a left handed or right handed system. I know i said that you always set it to +ve $d$ but i was wrong in the comments, sorry.

Now coming to your other question. You need the vectors $b,v,t$ and $E$ for creating a transformation matrix. Usually in raytracing you create your camera and initialize its transformation matrix to the standard case (aligned with world space) Then when you move your mouse or something you create a respective rotation matrix and transform the original camera matrix to keep up with these changes. Then when calculating the ray you multiply it as I said above to get ray direction easily. So you probably need to manage your own Camera first.

Since you aren't managing in this case you explicitly need to find these vectors. You mention you have the $w$ vector which is global up. $t$ is easy to find as you say

$t = T-E$

However remember this is the viewing direction not the basis vector. For right handed coordinate systems, the basis vector for $Z$ is $-V\_{dir}$

For $b$ which is Camera's right vector. You do,
$ w \times t = b$

This gets you the Camera's up vector. Then you do,

$ t \times b = v$

to get the Camera's up vector. This works as long as $t$ doesn't equal $w$ which is the global up.

So after you have these you can create a camera transformation matrix with $c\_1, c\_2, c\_3, c\_4 = b, v, t, E$ respectively.

EDIT2:-
Instead of following above approach you can also do Gram-Schmidt orthogonalization which is more standard in this case. Using this you get the Camera's up vector $v$ as

$v = w - (t.w)\hat{t}$

Then side vector as,

$b = v \times t$

For right handed systems. For left handed systems you need to change the ordering of cross products.

> **Comments:**
> **username_3**: Yes. you can see my open-source path tracer as a reference. It contains the createRay function.  https://github.com/username_3/Yune/blob/master/Yune-1.x/progressive-PT.cl  

---

### Answer by username_2 on 2019-01-18. Score: 3

First, the viewport size:
$$h\_x = 2\*d\*tan(\theta\_x/2)$$
$$h\_y = 2\*d\*tan(\theta\_y/2)$$

Each pixel (from your diagram) has the following size in the eye coordinate system:
$$W = h\_x / (k-1)$$
$$H = h\_y / (m-1)$$

Note that usually the field of view encompasses whole pixels and doesn't stop at the center of the edge pixels like your diagram shows.

If $P\_c$ is the viewport center in pixel coordinates, let:

$$\vec {P'\_{ij}} = P\_{ij} - P\_c$$

Therefore, $P\_{ij}$ in eye space becomes:
$$
[P\_{ij}]\_e =
\begin{pmatrix}
(W, 0) \* \vec {P'\_{ij}} \\
(0, H) \* \vec {P'\_{ij}} \\
d \\
\end{pmatrix}
$$

and in the standard base:
$$[P\_{ij}]\_{std} = (\vec b, \vec v, \vec t) \* [P\_{ij}]\_e$$

Normalize the one in the base you want to get $r\_{ij}$.

# Original answer

The last time I wanted to go from window coordinates (pixels) to eye coordinates, I followed the steps outlined here in the [OpenGL wiki](https://www.khronos.org/opengl/wiki/Compute_eye_space_from_window_space). Once you have the eye coordinates, you can just normalize the vector to obtain $r\_{ij}$.

> **Comments:**
> **username_2**: The *eye position* is known, but not the *pixel's position in the eye coordinate system* which is what you're looking for.  
> **username_0**: ok but the problem is that I not use OpenGL explicity and don't have that stuff described in wiki likes clip space, projection matrix etc. :( I have only simplified javascript used by [gpu.js](https://github.com/gpujs/gpu.js) library which allows me to perform any calculations on gpu - the kernel function (fragment shader written in simplidied javascript) takes on input i,j as this.thread.x and this.thread.y coordinates and thats all (plus input parameters which I describe on question).  
> **username_0**: Can you explain what is the meaning of $(W, 0) * \vec {P'_{ij}}$ and $[P_{ij}]_e$ and $(\vec b, \vec v, \vec t)$ and $[P_{ij}]_{std}$ (and how to get $r_{ij}$ from it) because I don't understand notation  
> **username_2**: Sorry that's just too much to explain. $(W, 0) * \vec {P'_{ij}}$ means multiply the x component of $\vec {P'_{ij}}$ by W. Read up on linear algebra and change of basis for more information. Also, you did not specify in which basis you want $r_[ij]$.  
> **username_0**: you not explain meaning of all symbols - sorry I dont understant. I dont indroduce any basis - because I need result in natural/canonical basis $\left[\begin{matrix} 1 &0 &0 \\ 0 &1 &0 \\ 0 &0 &1\end{matrix}\right]$ - which means that $E, T, w$ and $r_{ij}$ shoud not be transformed to any basis  
> **username_0**: you also not provide formula for viewport center $C=P_c$ which you use in your calculations  

---

### Answer by username_0 on 2019-01-21. Score: 0

## GPU friendly - full formulas

**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](https://username_0-kielczewski.github.io/fractals/mandelbulb.html) (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](https://en.wikipedia.org/wiki/Ray_tracing_(graphics)#Calculate_rays_for_rectangular_viewport).


---

