<p>Let's look at your formula:</p>

<pre><code>pixel_y = (y_world / z_world + 1) / 2 * ScreenHeight();
pixel_y = ScreenHeight() - 1 - pixel_y;
</code></pre>

<p>Let's call <code>y_world / z_world</code> for short <code>a</code>, <code>H</code> for <code>ScreenHeight()</code>. So you have:</p>

<pre><code>Y = (a + 1) / 2 *H
Y = H - 1 - Y
</code></pre>

<p>Let's replace the first in the second:</p>

<pre><code>   Y = H - 1 - (a + 1) / 2 * H
=&gt; Y = H * (1 - (a + 1) / 2) - 1
=&gt; Y = H * ((2 - a - 1) / 2) - 1
=&gt; Y = H * (1 - a) / 2 - 1
</code></pre>

<p>Which is the formula you said every one uses (except with an off-by-one error):</p>

<pre><code>pixel_y = (1 - y_world / z_world) / 2 * ScreenHeight();
</code></pre>

<p>Off-by-one error aside, looks like you have the right understanding, just didn't work out that the formula everyone uses is the optimized version of what you came up with.</p>

CC BY-SA 4.0
2020-01-29T06:11:42.507Z
2020-01-29T06:11:42.507Z
Shahbaz
<p>What is the correct way to invert the y axis during the 3D projection?</p>

<p>I see a lot a people doing:</p>

<pre class="lang-c prettyprint-override"><code>pixel_x = (x_world / z_world + 1) / 2 * ScreenWidth(); // This is right
pixel_y = (1 - y_world / z_world) / 2 * ScreenHeight();
</code></pre>

<p>But by inverting like this, we get an incorrect position of <code>pixel_y</code> because what this does is saying that <code>pixel_y</code> is 1 when <code>y_world</code> is -1 and 1 when <code>y_world</code> is -1. This seems right but don't forget that a point at <code>x == 1</code> in NDC space will map to <code>pixel_x = ScreenWidth()</code> and therefore won't be visible. In contrast, a point at <code>x == -1</code> in NDC space will map to <code>pixel_x = 0</code> and WILL be visible.
So if we invert like this, a point at <code>y == -1</code> will become <code>pixel_y == ScreenHeight()</code> and WON'T be visible but a point at <code>y == 1</code> will become <code>pixel_y == 0</code> and will be visible.</p>

<p>I think that the correct way of inverting y is by first calculating <code>pixel_y</code> like <code>pixel_x</code> and then and only then invert it in pixel space:</p>

<pre><code>pixel_y = (y_world / z_world + 1) / 2 * ScreenHeight(); // Y points up
pixel_y = ScreenHeight() - 1 - pixel_y; // now it points down
</code></pre>

<p>So what is the correct way to invert the y axis during the projection?</p>

CC BY-SA 4.0
2020-01-28T23:29:40.697Z
Right way to do that is setting the values directly on points (vertices) or using rotations.
Leonardo Fortes
<3d><projections><rasterizer>
Y axis inversion in 3D rasterization
Voko
# Y axis inversion in 3D rasterization

(Asked by: username_0 on 2020-01-28)

What is the correct way to invert the y axis during the 3D projection?

I see a lot a people doing:

```c
pixel_x = (x_world / z_world + 1) / 2 * ScreenWidth(); // This is right
pixel_y = (1 - y_world / z_world) / 2 * ScreenHeight();

```

But by inverting like this, we get an incorrect position of `pixel_y` because what this does is saying that `pixel_y` is 1 when `y_world` is -1 and 1 when `y_world` is -1. This seems right but don't forget that a point at `x == 1` in NDC space will map to `pixel_x = ScreenWidth()` and therefore won't be visible. In contrast, a point at `x == -1` in NDC space will map to `pixel_x = 0` and WILL be visible.
So if we invert like this, a point at `y == -1` will become `pixel_y == ScreenHeight()` and WON'T be visible but a point at `y == 1` will become `pixel_y == 0` and will be visible.

I think that the correct way of inverting y is by first calculating `pixel_y` like `pixel_x` and then and only then invert it in pixel space:

```
pixel_y = (y_world / z_world + 1) / 2 * ScreenHeight(); // Y points up
pixel_y = ScreenHeight() - 1 - pixel_y; // now it points down

```

So what is the correct way to invert the y axis during the projection?

**Tags:** 3d, projections, rasterizer

> **Comments:**
> **username_1**: Right way to do that is setting the values directly on points (vertices) or using rotations.  

---

## 1 answers

### Answer by username_2 on 2020-01-29. Score: 1 | Accepted answer

Let's look at your formula:

```
pixel_y = (y_world / z_world + 1) / 2 * ScreenHeight();
pixel_y = ScreenHeight() - 1 - pixel_y;

```

Let's call `y_world / z_world` for short `a`, `H` for `ScreenHeight()`. So you have:

```
Y = (a + 1) / 2 *H
Y = H - 1 - Y

```

Let's replace the first in the second:

```
   Y = H - 1 - (a + 1) / 2 * H
=> Y = H * (1 - (a + 1) / 2) - 1
=> Y = H * ((2 - a - 1) / 2) - 1
=> Y = H * (1 - a) / 2 - 1

```

Which is the formula you said every one uses (except with an off-by-one error):

```
pixel_y = (1 - y_world / z_world) / 2 * ScreenHeight();

```

Off-by-one error aside, looks like you have the right understanding, just didn't work out that the formula everyone uses is the optimized version of what you came up with.


---

