# Y axis inversion in 3D rasterization

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

I see a lot a people doing:

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?

• Right way to do that is setting the values directly on points (vertices) or using rotations. Jan 28 '20 at 23:29

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.