<p>The projection matrix distorts the view frustum (the volume the camera can see) into a unit cube. So everything with all coordinates in the range -1 to 1 after projection is potentially visible, and everything else can be clipped.</p>

<p>To make things further away look smaller, we need to divide by their Z distance. We can't put this value directly into the matrix since it is different for each point we want to project, so instead we place each point's Z into its projected W, giving (X, Y ,Z ,1) -> (X', Y', Z', Z), known as clip coordinates. This is then divided by the new W to give (X'/Z, Y'/Z, Z'/Z, 1),  known as normalized device coordinates. On the GPU this division happens automatically after the vertex shader and before clipping and rasterization.</p>

<p>The general form of a projection matrix is</p>

<pre><code>A 0 0 0
0 B 0 0
0 0 C D
0 0 1 0
</code></pre>

<p>The A and B terms relate to the field of view, higher values give a narrower view. Specifically, B is the cotangent of half the vertical view angle, and A is B/aspect ratio.</p>

<p>The C and D terms are bias and scale terms which map the near plane to -1 (0 in DirectX), and the far plane to 1. These are used for writes to the depth buffer to determine which objects occlude others. The depth mapping is actually a function of 1/Z, rather than Z, since this gives better precision close to the near plane, and allows perspective-correct interpolation.</p>

<p>Also note that in OpenGL, W' is -Z rather than Z, since we are using a right-handed coordinate system, with negative Z pointing into the screen.</p>

CC BY-SA 3.0
2017-07-22T11:19:35.910Z
Thanks for the answer. tell me If I am wrong here that we map frustum ranges to [-1,1] because OpenGL expects them to be in that range(because OpenGL performs clipping) so that clipping can occur properly. Am I correct?
videogamechef
CC BY-SA 3.0
2017-07-22T13:37:08.827Z
That's about right. The clipping occurs in automatic hardware on the GPU,  so it's broadly the same across different graphics APIs. Some specify -1 for the near plane and some specify 0. 0 is actually better for depth precision, for reasons Nathan Reed explains at http://reedbeta.com/blog/depth-precision-visualized/
russ
CC BY-SA 4.0
2021-09-15T19:40:47.310Z
@russ thanks for this concise and clear answer. One point I would like clarification on - Suppose I have a small mesh, say a cylinder. Are the occluded faces of this cylinder outside the unit cube after projection? Basically I am trying to map (x,y) touchscreen space on a mobile device to find the point in 3d space visible to the camera - however I am trying to ignore points that the camera doesn't see.

 Are you saying I can test for visibility of a vertex in the vertex shader by checking to make sure the bounds for XYZ are all -1 to 1 after projection?
blueether
CC BY-SA 3.0
2017-07-22T06:28:00.507Z
2017-07-22T06:28:00.507Z
russ
<p>I have been learning about projection matrix in OpenGL and I am finding it really hard to understand. All I know is that there are other configurations in the projection matrix besides placing z in w for perspective projection. What are those other numbers and why are they there? 
Thanks.</p>

CC BY-SA 3.0
2017-07-21T21:29:26.703Z
Considering (0, 0) as the center of the screen. If we divide any point we want to place on that screen by z it will get infinitely closer to (0, 0). This creates that vanishing effect. Farther back it goes, the larger the z, the more it vanishes. This is essentially what perspective projection is doing despite all the confusing notation, matrices, and what not. It also handles all the other transformations. Certain scalings and translations must be applied to get a point into screen coordinates.
Andrew Wilson
<opengl><perspective>
Is placing z value of vertex in w enough to achieve perspective projection in OpenGL?
videogamechef
# Is placing z value of vertex in w enough to achieve perspective projection in OpenGL?

(Asked by: username_0 on 2017-07-21)

I have been learning about projection matrix in OpenGL and I am finding it really hard to understand. All I know is that there are other configurations in the projection matrix besides placing z in w for perspective projection. What are those other numbers and why are they there?
Thanks.

**Tags:** opengl, perspective

> **Comments:**
> **username_1**: Considering (0, 0) as the center of the screen. If we divide any point we want to place on that screen by z it will get infinitely closer to (0, 0). This creates that vanishing effect. Farther back it goes, the larger the z, the more it vanishes. This is essentially what perspective projection is doing despite all the confusing notation, matrices, and what not. It also handles all the other transformations. Certain scalings and translations must be applied to get a point into screen coordinates.  

---

## 1 answers

### Answer by username_2 on 2017-07-22. Score: 4 | Accepted answer

The projection matrix distorts the view frustum (the volume the camera can see) into a unit cube. So everything with all coordinates in the range -1 to 1 after projection is potentially visible, and everything else can be clipped.

To make things further away look smaller, we need to divide by their Z distance. We can't put this value directly into the matrix since it is different for each point we want to project, so instead we place each point's Z into its projected W, giving (X, Y ,Z ,1) -> (X', Y', Z', Z), known as clip coordinates. This is then divided by the new W to give (X'/Z, Y'/Z, Z'/Z, 1), known as normalized device coordinates. On the GPU this division happens automatically after the vertex shader and before clipping and rasterization.

The general form of a projection matrix is

```
A 0 0 0
0 B 0 0
0 0 C D
0 0 1 0

```

The A and B terms relate to the field of view, higher values give a narrower view. Specifically, B is the cotangent of half the vertical view angle, and A is B/aspect ratio.

The C and D terms are bias and scale terms which map the near plane to -1 (0 in DirectX), and the far plane to 1. These are used for writes to the depth buffer to determine which objects occlude others. The depth mapping is actually a function of 1/Z, rather than Z, since this gives better precision close to the near plane, and allows perspective-correct interpolation.

Also note that in OpenGL, W' is -Z rather than Z, since we are using a right-handed coordinate system, with negative Z pointing into the screen.

> **Comments:**
> **username_0**: Thanks for the answer. tell me If I am wrong here that we map frustum ranges to [-1,1] because OpenGL expects them to be in that range(because OpenGL performs clipping) so that clipping can occur properly. Am I correct?  
> **username_2**: That's about right. The clipping occurs in automatic hardware on the GPU,  so it's broadly the same across different graphics APIs. Some specify -1 for the near plane and some specify 0. 0 is actually better for depth precision, for reasons Nathan Reed explains at http://reedbeta.com/blog/depth-precision-visualized/  
> **username_3**: @username_2 thanks for this concise and clear answer. One point I would like clarification on - Suppose I have a small mesh, say a cylinder. Are the occluded faces of this cylinder outside the unit cube after projection? Basically I am trying to map (x,y) touchscreen space on a mobile device to find the point in 3d space visible to the camera - however I am trying to ignore points that the camera doesn't see.   Are you saying I can test for visibility of a vertex in the vertex shader by checking to make sure the bounds for XYZ are all -1 to 1 after projection?  

---

