3
votes

According to this page: https://matthewwellings.com/blog/the-new-vulkan-coordinate-system/

The Vulkan coordinate system has:

  • The X axis increasing to the right
  • The Y axis increasing downwards
  • The Z axis increasing into the screen

In my own my own test, I can confirm the X and Y axis. However, for me, the -Z points into the screen, not +Z. By this, I mean:

  • As X increases, the scene moves to the left, because the camera moves to the right.
  • As Y increases, the scene moves up, because the camera moves downwards.
  • As Z increases, the scene moves away, because the camera is moving backwards.

I believe the linked page over my own learning code, so I'm not sure why I'm getting this effect.

My scene consists of a single textured quad. This is the code that I'm using:

C++

// No rotation
auto identMat = glm::mat4(1.0f);
auto rotAmount = 0.0f;
auto rotAxis = glm::vec3(0.0f, 0.0f, 1.0f);
mUBO.mModel = glm::rotate(identMat, rotAmount, rotAxis);

float eyeXPos = 0.0f;
float eyeYPos = 0.0f;
float eyeZPos = time * 1.0f;
auto eyePosition = glm::vec3(eyeXPos, eyeYPos, eyeZPos);
auto centerPosition = glm::vec3(0.0f, 0.0f, 0.0f);
auto upAxis = glm::vec3(0.0f, 1.0f, 0.0f);
mUBO.mView = glm::lookAt(eyePosition, centerPosition, upAxis);

const float kWindowWidth  = 800;
const float kWindowHeight = 600;
auto verticalFOV = glm::radians(45.0f);
auto aspectRatio = kWindowWidth / kWindowHeight;
auto nearPlane = 0.1f;
auto farPlane = 100.0f;
mUBO.mProj = glm::perspective(verticalFOV, aspectRatio, nearPlane, farPlane);

Vertex Shader

layout(location = 0) in vec2 inPosition;
// ...
gl_Position = ubo.proj * ubo.view * ubo.model * vec4(inPosition, 0.0, 1.0);

------------------------ EDIT ----------------------------------

I'm not losing sleep over this, or anything like that. But, since I decided to get myself a Vulkan t-shirt, I went ahead and created a test-case for this question, in case anyone is curious enough to run it. The function name that updates the UBO is called UpdateUniformBuffer(). The code is self contained, except that it needs the GLFW library. Also, it needs an up-to-date C++ compiler (I use VS2017).

t-shirt: https://teespring.com/vulkan#pid=2&cid=2397&sid=front

main.cpp https://pastebin.com/RWpNDfjc

TestRenderer.hpp https://pastebin.com/09TTF1e3

TestRenderer.cpp https://pastebin.com/wCDV0CEk

shader.vert https://pastebin.com/fb5f4hvF

shader.frag https://pastebin.com/CCVpnmwj

2
It would seems so, but Vulkan doesn't impose any coordinate system on Your 3D scene (only on a framebuffer/image/window level). I'm pretty sure that with some kind of a (not so complicated) math-magic, by modifying projection matrices, rendering state etc. it is possible to inverse 3D coordinate system so right is left, up is down, near is far and vice versa.Ekzuzy
@Ekzuzy: I understand that I can just multiply Z by -1 to get the effect as mentioned on the page that I linked. My question is more about why my code, as it currently stands, does not have that behavior by default (+Z into the screen).Dess
I'm not sure, but as far as I know You can't use GLMs matrices directly because they are designed for OpenGL which requires depth data to be in the [-1; 1] range and Vulkan uses the [0; 1] range. Maybe this causes different behavior?Ekzuzy

2 Answers

1
votes

As you're using glm, just define GLM_FORCE_DEPTH_ZERO_TO_ONE. It maps matrix depth ranges into Vulkans's [0..+1] range instead of OpenGL's [-1..+1] range.

0
votes

you can pick your own depth test from 8 options. So it doesn't matter which direction it goes as long as you clear the depth buffer to the correct value and use the correct depth test.

The biggest difference between opengl and vulkan is that NDC depth is from 0 to 1 rather than -1 to 1 it was in opengl. This helps avoid loss of precision when using floating point depth buffers.