<p>It depends on your setup. Of course you can normalize the direction to have length 1, but it is usually unnecessary. The following figure depicts the differences:</p>
<div class="s-table-container"><table class="s-table">
<thead>
<tr>
<th style="text-align: center;">Round frustum end face</th>
<th style="text-align: center;">Flat frustum end face</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><a href="https://i.sstatic.net/jywJ3.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/jywJ3.png" alt="enter image description here" /></a></td>
<td style="text-align: center;"><a href="https://i.sstatic.net/OR9EZ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/OR9EZ.png" alt="enter image description here" /></a></td>
</tr>
</tbody>
</table></div>
<p>Given the same step (for example, 128 ray marching steps, typical in NeRFs), you can guess which one is resulted from the normalized direction. The left one, for sure, since it reflects the <em>spherical wavefront</em> emitted from the camera. If we simply set z to be 1 (or -1), the forward direction will have the same step size, no matter which pixel we are on. This is more conventional in graphics textbooks, when we refer to camera frustum, we should be referring to shape as in the right figure. Normalizing the direction can be of use if you want the ray marching resolution to be direction-independent, since in the right case, the pixels closer to the screen edge will be more sparsely distributed in 3D space.</p>

CC BY-SA 4.0
2024-03-31T03:40:22.180Z
Thank you for detailed response! A more basic clarification perhaps - if my camera is at say (0,0,-5) and (for the invocation of the fragment shader for pixel (x, y))  the ray direction is set at (x, y, 1), it will actually intersect the XY plane at (5x, 5y, 0) - I suppose this is fine since it is a scaling factor that is applied to all positions uniformly ?
giorgio
CC BY-SA 4.0
2024-03-31T03:45:18.360Z
It seems to me like this is de facto a way to control field of view / focal length, eg the lower the z value we set in the ray direction corresponds to larger field of view?
giorgio
CC BY-SA 4.0
2024-03-31T12:04:22.540Z
"lower the z value we set in the ray direction corresponds to larger field of view" Yes. You can always calculate the FoV angle with your z value and the span in X, Y axis. Result of  arctan will get greater as z decreases.
Enigmatisms
CC BY-SA 4.0
2024-03-31T16:16:41.360Z
Thank you! Your answer about the further considerations to do with step size and the geometry of the frustum have answered the question I would’ve probably ask next now that I understand this :-) I originally got interested in ray marching in the context of 3D deep learning so the comment about usage in NeRFs is also very interesting.
giorgio
CC BY-SA 4.0
2024-04-01T01:42:39.110Z
For NeRFs, however, you should not tweak the z value and always leave it to 1 or -1 (when generate the ray directions from pixel coords). Since with `near`, `far` and number of samples per ray, you can obtain the starting point, end point and other samples on the ray with simple multiplication. For example: `near * ray_dir + camera_pos` is usually the starting point. Changing z values of rays will change the meaning of `near` and `far` (depth).
Enigmatisms
CC BY-SA 4.0
2024-03-31T02:17:55.040Z
2024-03-31T02:17:55.040Z
Enigmatisms
<p>I’ve recently gotten into shader art , using sites like shadertoy and various tutorials for getting started.</p>
<p>One thing I noticed is that a typical setup involves ray marching whereby:</p>
<ol>
<li>We set a hypothetical camera / eye, typically somewhere on the negative Z axis looking forward at the direction of XY plane</li>
<li>Our (2D) image plane is typically the XY plane</li>
<li>We then project out rays from the origin which is our eye / camera, and for each pixel (x, y) on our image we set the direction of the corresponding ray emanating from the eye and passing through this pixel to be (x, y, 1)</li>
</ol>
<p>My question is specifically about this ray direction - why is z simply set to 1 irrespective of the actual camera position on the z axis? Is this just a hack that doesn’t matter eg because of some subsequent normalization , does this represent some actual parameter of the camera (focal length etc) or otherwise? Most tutorials gloss over this without explanation so curious where this comes from.</p>

<raytracing><fragment-shader><raymarching>
Why is the z coordinate simply set to 1 for setting up direction of a ray in ray marching
giorgio
# Why is the z coordinate simply set to 1 for setting up direction of a ray in ray marching

(Asked by: username_0 on 2024-03-31)

I’ve recently gotten into shader art , using sites like shadertoy and various tutorials for getting started.

One thing I noticed is that a typical setup involves ray marching whereby:

1. We set a hypothetical camera / eye, typically somewhere on the negative Z axis looking forward at the direction of XY plane
2. Our (2D) image plane is typically the XY plane
3. We then project out rays from the origin which is our eye / camera, and for each pixel (x, y) on our image we set the direction of the corresponding ray emanating from the eye and passing through this pixel to be (x, y, 1)

My question is specifically about this ray direction - why is z simply set to 1 irrespective of the actual camera position on the z axis? Is this just a hack that doesn’t matter eg because of some subsequent normalization , does this represent some actual parameter of the camera (focal length etc) or otherwise? Most tutorials gloss over this without explanation so curious where this comes from.

**Tags:** raytracing, fragment-shader, raymarching


---

## 1 answers

### Answer by username_1 on 2024-03-31. Score: 3 | Accepted answer

It depends on your setup. Of course you can normalize the direction to have length 1, but it is usually unnecessary. The following figure depicts the differences:

| Round frustum end face | Flat frustum end face |
| --- | --- |
| [enter image description here](https://i.sstatic.net/jywJ3.png) | [enter image description here](https://i.sstatic.net/OR9EZ.png) |

Given the same step (for example, 128 ray marching steps, typical in NeRFs), you can guess which one is resulted from the normalized direction. The left one, for sure, since it reflects the *spherical wavefront* emitted from the camera. If we simply set z to be 1 (or -1), the forward direction will have the same step size, no matter which pixel we are on. This is more conventional in graphics textbooks, when we refer to camera frustum, we should be referring to shape as in the right figure. Normalizing the direction can be of use if you want the ray marching resolution to be direction-independent, since in the right case, the pixels closer to the screen edge will be more sparsely distributed in 3D space.

> **Comments:**
> **username_0**: Thank you for detailed response! A more basic clarification perhaps - if my camera is at say (0,0,-5) and (for the invocation of the fragment shader for pixel (x, y))  the ray direction is set at (x, y, 1), it will actually intersect the XY plane at (5x, 5y, 0) - I suppose this is fine since it is a scaling factor that is applied to all positions uniformly ?  
> **username_0**: It seems to me like this is de facto a way to control field of view / focal length, eg the lower the z value we set in the ray direction corresponds to larger field of view?  
> **username_1**: "lower the z value we set in the ray direction corresponds to larger field of view" Yes. You can always calculate the FoV angle with your z value and the span in X, Y axis. Result of  arctan will get greater as z decreases.  
> **username_0**: Thank you! Your answer about the further considerations to do with step size and the geometry of the frustum have answered the question I would’ve probably ask next now that I understand this :-) I originally got interested in ray marching in the context of 3D deep learning so the comment about usage in NeRFs is also very interesting.  
> **username_1**: For NeRFs, however, you should not tweak the z value and always leave it to 1 or -1 (when generate the ray directions from pixel coords). Since with `near`, `far` and number of samples per ray, you can obtain the starting point, end point and other samples on the ray with simple multiplication. For example: `near * ray_dir + camera_pos` is usually the starting point. Changing z values of rays will change the meaning of `near` and `far` (depth).  

---

