<p>I'm assuming your scene is constructed based on right-handed coordinates.</p>
<p>If you are using OpenGL, yes. If you are using Direct3D, no.</p>
<p>The projection matrix maps [-n, -f] into [0, 1]. This weird property comes from the fact that the eye coordinates are right-handed, but the clip space (NDC) uses left-handed coordinates. Hence the implementation of <code>ortho()</code>.</p>
<p>Direct3D uses a z-axis that goes outwards the screen. Implementations for Direct3D projection matrices will not produce negated z when coupled with your application.</p>

CC BY-SA 4.0
2020-07-10T16:08:33.940Z
Thanks! Just to clarify did you mean to write `In OpenGL screen-space (Normalized device coordinate), larger z value means FARTHER points.`? I mean if OpenGL uses z-axis that goes inwards the screen.
Lenny White
CC BY-SA 4.0
2020-07-12T11:00:44.050Z
[From this link:](http://www.songho.ca/opengl/gl_projectionmatrix.html) "Note that the eye coordinates are defined in the right-handed coordinate system, but NDC uses the left-handed coordinate system. That is, the camera at the origin is looking along -Z axis in eye space, but it is looking along +Z axis in NDC." --- So larger values mean farther away in NDC
wychmaster
CC BY-SA 4.0
2020-07-12T11:40:57.037Z
So this is not correct: "In OpenGL screen-space (Normalized device coordinate), larger z value means closer points."
wychmaster
CC BY-SA 4.0
2020-07-13T02:43:14.813Z
I see. I was wrong indeed. The misunderstanding came from my thought that the projection matrix maps [n, f] to [0, 1]. What actually happens is the matrix maps [-n, -f] to [0, 1]. I'll edit the answer accordingly. Thanks.
intergula
CC BY-SA 4.0
2020-07-10T04:39:48.520Z
2020-07-13T02:52:21.510Z
2020-07-13T02:52:21.510Z
intergula
<blockquote>
<p>What could be the purpose behind that?</p>
</blockquote>
<p>Have a look at the first lines and the first image in the Perspective Projection section of <a href="http://www.songho.ca/opengl/gl_projectionmatrix.html" rel="nofollow noreferrer">this link</a>. For the answer to your question, it is not important that you used an orthographic projection, even though there is also a corresponding section in the link.</p>
<p>The issue is how OpenGL defines its coordinate systems. Quote from the link:</p>
<blockquote>
<p>Note that the eye coordinates are defined in the right-handed coordinate system, but NDC uses the left-handed coordinate system. That is, the camera at the origin is looking along -Z axis in eye space, but it is looking along +Z axis in NDC.</p>
</blockquote>
<p>So if you transform between them, you need to swap the z-axis. This is the whole purpose behind it, switching the handedness of the coordinate systems.</p>
<blockquote>
<p>Is it standard to negate the z coordinate when constructing projection matrix?</p>
</blockquote>
<p>Depends on your API and how the coordinate systems are defined. In OpenGL, you need to do this.</p>

CC BY-SA 4.0
2020-07-10T07:24:19.800Z
2020-07-12T11:21:19.150Z
2020-07-12T11:21:19.150Z
wychmaster
<p>I constructed an orthographic projection matrix from  <a href="https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/orthographic-projection-matrix" rel="nofollow noreferrer">this</a> article on scratchpixel.com:</p>
<pre><code>Matrix4 ortho(float l, float r, float b, float t, float n, float f) {
   return Matrix4(
       2/(r-l), 0, 0, -(r+l)/(r-l), //row 0
       0, 2/(t-b), 0, -(t+b)/(t-b), //row 1
       0, 0, -2/(f-n), -(f+n)/(f-n), //row 2
       0, 0, 0, 1 //row 3
   );
}
</code></pre>
<p>, where <code>r, l, t, b, n, f</code> are right, left, top, bottom, near and far corners of the view box.</p>
<p>Now I tested out this matrix using the default parameters of the view box <code>ortho(-1, 1, -1, 1, -1, 1)</code> to see if I get an identity matrix. However I'm getting:</p>
<pre><code> 1, 0, 0, 0,
 0, 1, 0, 0,
 0, 0, -1, 0,
 0, 0, 0, 1
</code></pre>
<p>Basically this will result in z coordinate of every transformed point to be negated.</p>
<p>Is it standard to negate the z coordinate when constructing projection matrix? What could be the purpose behind that?</p>

CC BY-SA 4.0
2020-07-10T07:23:50.877Z
In my opinion flipping $Z$ is both confusing and unnecessary. It changes the handedness of the different spaces. It's just an arbitrary decision that was made for OpenGL afaik.
lightxbulb
<opengl><c++><linear-algebra>
Why negate z when constructing projection matrix OpenGL
Lenny White
# Why negate z when constructing projection matrix OpenGL

(Asked by: username_0 on 2020-07-09)

I constructed an orthographic projection matrix from [this](https://www.scratchapixel.com/lessons/3d-basic-rendering/perspective-and-orthographic-projection-matrix/orthographic-projection-matrix) article on scratchpixel.com:

```
Matrix4 ortho(float l, float r, float b, float t, float n, float f) {
   return Matrix4(
       2/(r-l), 0, 0, -(r+l)/(r-l), //row 0
       0, 2/(t-b), 0, -(t+b)/(t-b), //row 1
       0, 0, -2/(f-n), -(f+n)/(f-n), //row 2
       0, 0, 0, 1 //row 3
   );
}

```

, where `r, l, t, b, n, f` are right, left, top, bottom, near and far corners of the view box.

Now I tested out this matrix using the default parameters of the view box `ortho(-1, 1, -1, 1, -1, 1)` to see if I get an identity matrix. However I'm getting:

```
 1, 0, 0, 0,
 0, 1, 0, 0,
 0, 0, -1, 0,
 0, 0, 0, 1

```

Basically this will result in z coordinate of every transformed point to be negated.

Is it standard to negate the z coordinate when constructing projection matrix? What could be the purpose behind that?

**Tags:** opengl, c++, linear-algebra

> **Comments:**
> **username_1**: In my opinion flipping $Z$ is both confusing and unnecessary. It changes the handedness of the different spaces. It's just an arbitrary decision that was made for OpenGL afaik.  

---

## 2 answers

### Answer by username_2 on 2020-07-10. Score: 1

I'm assuming your scene is constructed based on right-handed coordinates.

If you are using OpenGL, yes. If you are using Direct3D, no.

The projection matrix maps [-n, -f] into [0, 1]. This weird property comes from the fact that the eye coordinates are right-handed, but the clip space (NDC) uses left-handed coordinates. Hence the implementation of `ortho()`.

Direct3D uses a z-axis that goes outwards the screen. Implementations for Direct3D projection matrices will not produce negated z when coupled with your application.

> **Comments:**
> **username_0**: Thanks! Just to clarify did you mean to write `In OpenGL screen-space (Normalized device coordinate), larger z value means FARTHER points.`? I mean if OpenGL uses z-axis that goes inwards the screen.  
> **username_3**: [From this link:](http://www.songho.ca/opengl/gl_projectionmatrix.html) "Note that the eye coordinates are defined in the right-handed coordinate system, but NDC uses the left-handed coordinate system. That is, the camera at the origin is looking along -Z axis in eye space, but it is looking along +Z axis in NDC." --- So larger values mean farther away in NDC  
> **username_3**: So this is not correct: "In OpenGL screen-space (Normalized device coordinate), larger z value means closer points."  
> **username_2**: I see. I was wrong indeed. The misunderstanding came from my thought that the projection matrix maps [n, f] to [0, 1]. What actually happens is the matrix maps [-n, -f] to [0, 1]. I'll edit the answer accordingly. Thanks.  

---

### Answer by username_3 on 2020-07-10. Score: 1

> What could be the purpose behind that?

Have a look at the first lines and the first image in the Perspective Projection section of [this link](http://www.songho.ca/opengl/gl_projectionmatrix.html). For the answer to your question, it is not important that you used an orthographic projection, even though there is also a corresponding section in the link.

The issue is how OpenGL defines its coordinate systems. Quote from the link:

> Note that the eye coordinates are defined in the right-handed coordinate system, but NDC uses the left-handed coordinate system. That is, the camera at the origin is looking along -Z axis in eye space, but it is looking along +Z axis in NDC.

So if you transform between them, you need to swap the z-axis. This is the whole purpose behind it, switching the handedness of the coordinate systems.

> Is it standard to negate the z coordinate when constructing projection matrix?

Depends on your API and how the coordinate systems are defined. In OpenGL, you need to do this.


---

