My Z-axis flipped after changing the viewport

So, as far as I know, “basic” the Vulkan coordinate system looks like this.

Now if I want to rotate an object along the Z axis

//We'll use chrono to make sure that the geometry rotates 90 degrees per second regardless of frame rate.
static auto startTime = std::chrono::high_resolution_clock::now();
auto currentTime = std::chrono::high_resolution_clock::now();
float time = std::chrono::duration<float, std::chrono::seconds::period>(currentTime - startTime).count();

//time cannot be a negative number
mvp_matrixes.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(45.0f), glm::vec3(0.0f, 0.0f, 1.0f));
mvp_matrixes.view = glm::mat4(1.0f);
mvp_matrixes.projection = glm::mat4(1.0f);

then on my screen it will rotate clockwise and this is correct.

However, I decided to flip the Y axis by configuring the viewport as follows:

VkViewport viewport{};
viewport.x = 0.0f;
viewport.y = (float)swapchainExtent.height;
viewport.width = (float)swapchainExtent.width;
viewport.height = -(float)swapchainExtent.height;
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;

And now, I specify the usual (such as would be in OpenGL) coordinates for my square.

const std::vector<Vertex> vertexes = {
    //coordinates        //colours            //UV-coordinates
	{{-0.5f, 0.5f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 0.0f}},
	{{0.5f, 0.5f, 0.0f}, {0.0f, 1.0f, 0.0f}, {1.0f, 0.0f}},
	{{0.5f, -0.5f, 0.0f}, {0.0f, 0.0f, 1.0f}, {1.0f, 1.0f}},
	{{-0.5f, -0.5f, 0.0f}, {1.0f, 1.0f, 1.0f}, {0.0f, 1.0f}}

const std::vector<uint16_t> indices = {
	0, 1, 2, 2, 3, 0

However, now my square is spinning counterclockwise.
I’m looking at it correctly, on its front side, since I set VK_CULL_MODE_BACK_BIT in the rasterizer settings.
Since my square is now rotating counterclockwise, I assume that the Z axis has started looking at me from the screen, although it used to look away from me towards the screen.

If you flip an image upside down then obviously any rotation that you did before looks like it goes the other way.

The Z stays the same. Only the coordinate system will change handedness. Well, it is simpler that it sounds. More like, the depth (so called “z”) is unrelated and simply goes to different 2D image. Nothing really looks at you from the screen, because at that point it is just 2D image.

Cull mode is also defined in terms of x and y framebuffer coordinates and is unrelated to z. Well actually if z was flipped (into negative), then nothing would be shown as it would all get clipped.

1 Like

Hmm, I get it.
But what about the fact that the view matrix does not work for me?
Here I am trying to “stand” on the point (0;0;-3) and look at the point (0;0;0), but I don’t see anything, even if I stand at the point (0;0;3).
I also tried to specify the vector (0, -1, 0) as an upward vector.

mvp_matrixes.model = glm::mat4(1.0f);
mvp_matrixes.view = glm::lookAt(glm::vec3(0.0f, 0.0f, -3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
mvp_matrixes.projection = glm::mat4(1.0f);

What do you expect to see here? eye = (0, 0, -3) will basically push everything away by 3. But if your original z is 0, then it is pushed to -3, which is outside the clip cube (which has only z between 0 and 1), so that primitive is gonna get clipped.

1 Like

I’ve recently created a blog post which might be useful to you: Setting Up a Proper Projection Matrix for Vulkan
(Feel free to provide feedback or start a discussion about anything that might be described in an unclear manner.)

1 Like

Alright, left a few notes on the Disqus there.