Open jjYBdx4IL opened 3 years ago
I can't remember where it is explained, but if I recall correctly, this is because OpenGL has not the same image coordinates convention as Vulkan, and GLM was made for GL, so we need to inverse the image coordinate to avoid having an upside-down result
Found the explanation: https://github.com/Overv/VulkanTutorial/blob/master/en/05_Uniform_buffers/00_Descriptor_layout_and_buffer.md near the end
Exactly. That's what the left hand macro is for.
That can't be the only thing, because if I define GLM_FORCE_LEFT_HANDED
and remove the -1
multiplication, I get an upside down image. It's only upright if I proceed to flip the up axis in the glm::lookAt
.
For example 27 I have reconstructed 3 changes from my own implementation:
Header section:
#define GLM_FORCE_LEFT_HANDED
#include <glm/ext.hpp> // for glm::rotate
At end of loadModel:
// fix model coordinates
glm::mat4 rot = glm::rotate(glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f))
* glm::rotate(glm::radians(90.0f), glm::vec3(1.0f, 0.0f, 0.0f));
for (Vertex& v : vertices) {
v.pos = rot * glm::vec4(v.pos, 1.0f);
}
updateUniformBuffer:
ubo.model = glm::rotate(glm::mat4(1.0f), time * glm::radians(90.0f), glm::vec3(0.0f, 1.0f, 0.0f));
ubo.view = glm::lookAt(glm::vec3(2.0f, -2.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
Though I have to admit that I'm not quite sure why the up-vector has a positive y component. Shouldn't that be negative in Vulkan coords? Probably because the model coords are still upside down in Vulkan coords? I did only rotate the model after import after all.
The proper import of the object model and its proper alignment along Vulkan coordinates probably warrants a separate chapter.
The model was exported with positive Y coordinates meaning up, so that would be the convention for the view transform in this case.
The proper fix to this issue is not to do this at run-time, but instead using a compiler switch for the shaders:
-finvert-y
for glslc-fvk-invert-y
for dxcThe compiler switches will add code that inverts the y-coordinate for outputs of the VS/GS/TE shader stages to comply with the Vulkan coordinate system.
@crud89 Assuming that you mean --invert-y
, it doesn't seem to make any difference for me.
Going by this article it seems that the solution could be:
#define GLM_FORCE_LEFT_HANDED
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;
frontFace
:
rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE;
@crud89 Assuming that you mean
--invert-y
, it doesn't seem to make any difference for me.
glslc --help
says it's -finvert-y
for me. 🤔
It's weird, that it does not work for you. I tried with both (dxc and glslc) and both fixed the issues. Handedness should not influence the y-coordinate, only the z-coordinate (whether positive or negative is pointing forward).
The tutorial flips the sign of the (V)P1,1 matrix. Ultimately this corresponds to multiplying the VP matrix with a matrix that looks like this:
1 0 0 0
0 -1 0 0
0 0 1 0
0 0 0 1
This transform does nothing else than inverting the y coordinate of the result, so basically this is the same as using the compiler switch.
The article you linked does two things:
So there are many fixes to this issue. I personally prefer using the compiler switches, because it appears to be the most portable solution. I am, however, not sure if it might be an issue with glslc and glsl shaders (since I am using hlsl).
glslc --help
says it's-finvert-y
for me. 🤔
Ah right, I just noticed that my local compiling script was still using glslangValidator
.
Is this explained?:
https://github.com/Overv/VulkanTutorial/blob/master/code/27_model_loading.cpp#L1331
I think you need to add
to avoid that "fix".