Search code examples
glslvulkan

Confused about Vulkan view matrix


I'm trying to understand view matrices. I'm playing around with a vertex shader to manipulate view matrix values directly. I'm confused by the coordinate system that the view matrix seems to be in.

#version 450

layout(location = 0) out vec4 outColor;

layout (push_constant) uniform PushConstants {
    mat4 proj;
} pc;

const vec2 kGeometry[] = vec2[](
    vec2(-1, -1), vec2(1, -1), vec2(1, 1),
    vec2(1,1), vec2(-1, 1), vec2(-1, -1)
);

const vec4 kColor[] = vec4[](
    vec4(1, 0, 0, 1), vec4(0, 1, 0, 1), vec4(0, 0, 1, 1),
    vec4(1, 0, 1, 1), vec4(1, 1, 0, 1), vec4(0, 1, 1, 1)
);

void main() {
    vec2 p = kGeometry[gl_VertexIndex];
    outColor = kColor[gl_VertexIndex];

    mat4 view = mat4(1);
    view[3].z = -3; // !!! Translate camera on Z. Expected +3, not -3 to see quad.

    gl_Position =  pc.proj * view * vec4(p, 0, 1);
}

I'll refer to these diagrams:

enter image description here

The drawn quad, with the view matrix at (0, 0, -3):

enter image description here

A) I expected both the model vertices and view matrix to be in the right hand coord system depicted by diagram #1, (D1). That's a right-handed coord-system with +Y pointing down, and +Z into the screen.

B) D2 shows a quad on the screen, with center at (0,0,0). I expected the camera to be pointing at -Z; this is shown by the eye.

C) D3 shows what I expected to happen if I translate the view matrix on -Z by 3, so that it ends up at (0,0,-3). I expected the quad to be behind the camera, and thus not visible. However, positioning the camera at this location does show the quad.

D) D4 shows what the coord system the view matrix actually seems to be in. The camera appears to look +Z.

E) D5 Shows what happens if I translate the view matrix to (2, 3, -5). The quad appears on the right bottom of the window. The camera seems to be looking down +Z.

F) D6 Shows what happens if I inverse(viewMat). Here, I position the view matrix at (2, 3, 5). The quad appears in the top-left corner. The camera seems to be looking down -Z axis, but the coord-system seems to be left-handed.

I think the model vertices are translated as a RH coord-system, as in D1. But, when I translate the view matrix, the results are not what I expected them to be.

I'm not 100% sure what coord system the view matrix is in, and I don't understand why it's not RH, as D1.


Solution

  • By default for Vulkan the output clip-space coordinates from the vertex shader are -1 to 1 in XY, and 0 to 1 in Z. The Y origin is flipped compared to OpenGL (top left, Y pointing downwards).

    What coordinate system you take to get from object coords into clip-space is entirely up to you - it's entirely application dependent and not mandated by the API. You just need to make sure that the matrices and the models agree with each other ...

    The unknown here is your projection matrix - what's the value of pc.proj? ... but I predict your W divisor is set to -Z (i.e. camera is looking down -ve Z, which is what flips your -3 to a positive value in clip-space due to the perspective division).