<blockquote>
  <p>In this case, the geometry of similar triangles ABC and ADE is used to determine the height of D via the solution of DE. It is obvious that if the near plane is at 0 (AE=0), then a division by 0 occurs -- hence, why the near plane cannot be located at position 0.</p>
</blockquote>

<p>This is <em>not</em> why the nearZ plane cannot be zero. The goal of perspective math is not to project the E onto the near plane. If you look at the actual perspective matrices, you'll find that the nearZ <em>only</em> applies to the computed clip-space Z coordinate, not the X and Y.</p>

<p>Remember: projection is essentially transforming a position such that you lose one or more dimensions. You're projecting from 3D space to 2D space. So projection is removing the Z component, projecting a scene into a 2D region of space. Orthographic projection just discards the Z; perspective projection does something more complex, rescaling the X and Y based on the Z.</p>

<p>Of course, we're not <em>really</em> doing that; Z still exists. Otherwise, the depth buffer wouldn't work. But the basic perspective projection math does not define how the Z is computed.</p>

<p>Therefore, we can compute the Z however we want. The traditional depth equation (for OpenGL's standard NDC space) is where near/farZ come from:</p>

<p><span class="math-container">$$Z_{ndc} = \frac{\frac{Z_{camera}(F + N)}{N - F} + \frac{2NF}{N - F}}{-Z_{camera}}$$</span></p>

<p><code>N</code> and <code>F</code> are near/farZ, respectively. If <code>N</code> is zero, then the equation degenerates:</p>

<p><span class="math-container">$$Z_{ndc} = \frac{\frac{Z_{camera}(F)}{-F} + 0}{-Z_{camera}}$$</span>
<span class="math-container">$$Z_{ndc} = \frac{-Z_{camera}}{-Z_{camera}}$$</span>
<span class="math-container">$$Z_{ndc} = 1$$</span></p>

<p>Oops.</p>

<p>So your question really is why we use depth computations (which again, don't really have anything to do with perspective projection) that require near/farZ values like this.</p>

<p>This equation, and those like it, has some very nice properties. It plays well with the clip-space W component needed for perspective projection (the division by <span class="math-container">$-Z_{camera}$</span>). But it also has the effect of being a non-linear Z projection. It puts more precision at the front of the scene than in the distance. And that's generally where you <em>need</em> depth precision the most.</p>

<p>There are alternative ways to compute the clip-space Z. You can use a linear method, which doesn't forbid near Z from being 0. You can also use a method that allows for an infinitely distant far Z (but still relies on near Z); this requires a floating-point Z buffer, though. And so forth.</p>

<p>You haven't really shown your code, so I can't say if it truly "works". The clip-space W in particular is important, as it is used for <a href="https://nicolbolas.github.io/oldtut/Texturing/Tut14%20Interpolation%20Redux.html" rel="nofollow noreferrer">perspective-correct interpolation of vertex data</a>. If you set it to one, then you won't get proper perspective-correct interpolation. </p>

CC BY-SA 4.0
2017-05-16T16:08:20.913Z
2020-01-04T03:51:34.203Z
2020-01-04T03:51:34.203Z
Nicol Bolas
<p>The near and far planes of a viewing frustum aren't needed for simple 3D→2D projection. What the near and far planes actually do, in a typical rasterizer setup, is define the range of values for the depth buffer. </p>

<p>Depths in the [near, far] range will be mapped into [0, 1] to be stored in the depth buffer. However, the depths aren't simply linearly rescaled. Instead, we use a hyperbolic mapping for depth: the value stored in the depth buffer is the <em>reciprocal</em> of the actual depth distance, with a scale and offset applied.</p>

<p><a href="https://i.sstatic.net/2Ovvk.png" rel="noreferrer"><img src="https://i.sstatic.net/2Ovvk.png" alt="Graph of standard hyperbolic depth mapping"></a></p>

<p>If you look at this curve and imagine moving the near plane value toward $z = 0$, the corresponding point on the $1/z$ curve would shoot up toward infinity. The math blows up and the depth buffer becomes useless (it suffers a catastrophic loss of precision).</p>

<p>The reason why we use the reciprocal instead of some other function of depth is basically convenience: the reciprocal depth interpolates nicely in screen space, and it fits naturally into the mathematical framework of perspective projections: there's already a divide by $z$ being applied to the $x, y$ coordinates.</p>

<p>If you'd like to know more, I have a short article on the topic: <a href="http://reedbeta.com/blog/depth-precision-visualized/" rel="noreferrer">Depth Precision Visualized</a>.</p>

CC BY-SA 3.0
2017-05-17T18:01:32.443Z
I want to understand the purpose of the depth buffer. I've only attempted a wireframe renderer, so I didn't consider depth when plotting the 3D points to a 2D screen (I could plot the points and lines in any order and it would look right).

Is the purpose of the depth buffer to maintain a record of the Z distance of each point once it's been projected to 2D so that solid polygons may be drawn in the correct order? Is this why I didn't require a near/far plane in my simple wireframe visualizer?
William Breathitt Gray
CC BY-SA 3.0
2017-05-17T18:31:31.577Z
@VilhelmGray Right, the depth buffer records the depth of the nearest surface at each pixel, so that when rasterizing a triangle, you can tell if it should be occluded by the previously rendered pixels or not. But if you don't care about depth sorting (because you're drawing wireframe, you've pre-sorted your triangles already, or some other reason) then there's no need for a depth buffer.
Nathan Reed
CC BY-SA 3.0
2017-05-17T02:19:48.653Z
2017-05-17T02:19:48.653Z
Nathan Reed
<p>I'm learning about 3D computer graphics, but I'm having a hard time understanding why the <a href="https://en.wikipedia.org/wiki/Viewing_frustum" rel="noreferrer">near plane of a viewing frustum</a> can not be placed at z position $0$ (right at the camera).</p>

<p>I can understand conceptually that the near plane is essentially the retinal canvas -- so by definition it must exist to some extent -- but I have trouble understanding why the near plane isn't simply an abstract concept where it's actual position is infinitesimally close to the camera position, as opposed to a definite z position away.</p>

<p>In several explanations, the following formula is given to explain why $0$ cannot be used as the near plan position (where $A$ is the camera position, $B$ is an object vertex, and $D$ is the perspective projection of point $B$ onto the near plane):</p>

<p><a href="https://i.sstatic.net/gO1nR.png" rel="noreferrer"><img src="https://i.sstatic.net/gO1nR.png" alt="similar right triangles"></a></p>

<p>$${ BC \over AC } = { DE \over AE }$$</p>

<p>In this case, the geometry of similar triangles $ABC$ and $ADE$ is used to determine the height of $D$ via the solution of $DE$. It is obvious that if the near plane is at $0$ ($AE = 0$), then a division by $0$ occurs -- hence, why the near plane cannot be located at position $0$.</p>

<p><strong>However, why is this method used to determine the position of $D$ on the canvas?</strong></p>

<p>I've written a simple raycasting visualizer before and didn't have an explicitly defined near plane. In my engine, I simply defined a $60^\circ$ field of view and divided the number pixels on my screen among that field of view. For example, for a $300$x$300$ screen:</p>

<p>$$1\text{ pixel} = 300/60^\circ = 5^\circ$$</p>

<p>Next, I found the angle between my camera and the object vertex ($\angle BAC$) and divided it by $5^\circ$ to acquire the pixel coordinate on my screen. In this method, no explicit near plane was necessary and I used my actual camera position to determine the angle.</p>

<p><strong>So how was I able to perform a perspective projection without a near plane in my raycasting method?</strong></p>

CC BY-SA 3.0
2017-05-16T15:08:56.053Z
One key point of the near and far planes is that they set the how the depth changes throughout the region between them.
ratchet freak
<raytracing><projections><perspective><mathematics>
How am I able to perform perspective projection without a near plane?
William Breathitt Gray
# How am I able to perform perspective projection without a near plane?

(Asked by: username_0 on 2017-05-16)

I'm learning about 3D computer graphics, but I'm having a hard time understanding why the [near plane of a viewing frustum](https://en.wikipedia.org/wiki/Viewing_frustum) can not be placed at z position $0$ (right at the camera).

I can understand conceptually that the near plane is essentially the retinal canvas -- so by definition it must exist to some extent -- but I have trouble understanding why the near plane isn't simply an abstract concept where it's actual position is infinitesimally close to the camera position, as opposed to a definite z position away.

In several explanations, the following formula is given to explain why $0$ cannot be used as the near plan position (where $A$ is the camera position, $B$ is an object vertex, and $D$ is the perspective projection of point $B$ onto the near plane):

[![similar right triangles](https://i.sstatic.net/gO1nR.png)](https://i.sstatic.net/gO1nR.png)

$${ BC \over AC } = { DE \over AE }$$

In this case, the geometry of similar triangles $ABC$ and $ADE$ is used to determine the height of $D$ via the solution of $DE$. It is obvious that if the near plane is at $0$ ($AE = 0$), then a division by $0$ occurs -- hence, why the near plane cannot be located at position $0$.

**However, why is this method used to determine the position of $D$ on the canvas?**

I've written a simple raycasting visualizer before and didn't have an explicitly defined near plane. In my engine, I simply defined a $60^\circ$ field of view and divided the number pixels on my screen among that field of view. For example, for a $300$x$300$ screen:

$$1\text{ pixel} = 300/60^\circ = 5^\circ$$

Next, I found the angle between my camera and the object vertex ($\angle BAC$) and divided it by $5^\circ$ to acquire the pixel coordinate on my screen. In this method, no explicit near plane was necessary and I used my actual camera position to determine the angle.

**So how was I able to perform a perspective projection without a near plane in my raycasting method?**

**Tags:** raytracing, projections, perspective, mathematics

> **Comments:**
> **username_1**: One key point of the near and far planes is that they set the how the depth changes throughout the region between them.  

---

## 2 answers

### Answer by username_3 on 2017-05-17. Score: 12 | Accepted answer

The near and far planes of a viewing frustum aren't needed for simple 3D→2D projection. What the near and far planes actually do, in a typical rasterizer setup, is define the range of values for the depth buffer.

Depths in the [near, far] range will be mapped into [0, 1] to be stored in the depth buffer. However, the depths aren't simply linearly rescaled. Instead, we use a hyperbolic mapping for depth: the value stored in the depth buffer is the *reciprocal* of the actual depth distance, with a scale and offset applied.

[![Graph of standard hyperbolic depth mapping](https://i.sstatic.net/2Ovvk.png)](https://i.sstatic.net/2Ovvk.png)

If you look at this curve and imagine moving the near plane value toward $z = 0$, the corresponding point on the $1/z$ curve would shoot up toward infinity. The math blows up and the depth buffer becomes useless (it suffers a catastrophic loss of precision).

The reason why we use the reciprocal instead of some other function of depth is basically convenience: the reciprocal depth interpolates nicely in screen space, and it fits naturally into the mathematical framework of perspective projections: there's already a divide by $z$ being applied to the $x, y$ coordinates.

If you'd like to know more, I have a short article on the topic: [Depth Precision Visualized](http://reedbeta.com/blog/depth-precision-visualized/).

> **Comments:**
> **username_0**: I want to understand the purpose of the depth buffer. I've only attempted a wireframe renderer, so I didn't consider depth when plotting the 3D points to a 2D screen (I could plot the points and lines in any order and it would look right).  Is the purpose of the depth buffer to maintain a record of the Z distance of each point once it's been projected to 2D so that solid polygons may be drawn in the correct order? Is this why I didn't require a near/far plane in my simple wireframe visualizer?  
> **username_3**: @VilhelmGray Right, the depth buffer records the depth of the nearest surface at each pixel, so that when rasterizing a triangle, you can tell if it should be occluded by the previously rendered pixels or not. But if you don't care about depth sorting (because you're drawing wireframe, you've pre-sorted your triangles already, or some other reason) then there's no need for a depth buffer.  

---

### Answer by username_2 on 2017-05-16. Score: 7

> In this case, the geometry of similar triangles ABC and ADE is used to determine the height of D via the solution of DE. It is obvious that if the near plane is at 0 (AE=0), then a division by 0 occurs -- hence, why the near plane cannot be located at position 0.

This is *not* why the nearZ plane cannot be zero. The goal of perspective math is not to project the E onto the near plane. If you look at the actual perspective matrices, you'll find that the nearZ *only* applies to the computed clip-space Z coordinate, not the X and Y.

Remember: projection is essentially transforming a position such that you lose one or more dimensions. You're projecting from 3D space to 2D space. So projection is removing the Z component, projecting a scene into a 2D region of space. Orthographic projection just discards the Z; perspective projection does something more complex, rescaling the X and Y based on the Z.

Of course, we're not *really* doing that; Z still exists. Otherwise, the depth buffer wouldn't work. But the basic perspective projection math does not define how the Z is computed.

Therefore, we can compute the Z however we want. The traditional depth equation (for OpenGL's standard NDC space) is where near/farZ come from:

$$Z\_{ndc} = \frac{\frac{Z\_{camera}(F + N)}{N - F} + \frac{2NF}{N - F}}{-Z\_{camera}}$$

`N` and `F` are near/farZ, respectively. If `N` is zero, then the equation degenerates:

$$Z\_{ndc} = \frac{\frac{Z\_{camera}(F)}{-F} + 0}{-Z\_{camera}}$$
$$Z\_{ndc} = \frac{-Z\_{camera}}{-Z\_{camera}}$$
$$Z\_{ndc} = 1$$

Oops.

So your question really is why we use depth computations (which again, don't really have anything to do with perspective projection) that require near/farZ values like this.

This equation, and those like it, has some very nice properties. It plays well with the clip-space W component needed for perspective projection (the division by $-Z\_{camera}$). But it also has the effect of being a non-linear Z projection. It puts more precision at the front of the scene than in the distance. And that's generally where you *need* depth precision the most.

There are alternative ways to compute the clip-space Z. You can use a linear method, which doesn't forbid near Z from being 0. You can also use a method that allows for an infinitely distant far Z (but still relies on near Z); this requires a floating-point Z buffer, though. And so forth.

You haven't really shown your code, so I can't say if it truly "works". The clip-space W in particular is important, as it is used for [perspective-correct interpolation of vertex data](https://username_2.github.io/oldtut/Texturing/Tut14%20Interpolation%20Redux.html). If you set it to one, then you won't get proper perspective-correct interpolation.


---

