vulkan的NDC默认使用的Y轴向下的右手坐标系以及Y轴向下的FrameBuffer。

我这里使用的方案为:顶点逆序为正面、背面剔除、NDC的Y轴向上,FrameBuffer的Y轴向下,基本和dx一致。

通过反转viewport可以达到假反转NDC的效果,而反转viewport并不影响FrameBuffer的朝向,借此和dx标准保持一致。

在Vulkan1.0中使用VK_KHR_maintenance1扩展,该扩展在Vulkan1.1中成为标准。

通过添加一个宏VULKAN_FLIPPING_VIEWPORT来控制是否反转

        VkViewport viewport{};
#if VULKAN_FLIPPING_VIEWPORT
        viewport.x = x;
        viewport.y = y + height;
        viewport.width = width;
        viewport.height = -height;
#else
        viewport.x = x;
        viewport.y = y;
        viewport.width = width;
        viewport.height = height;
#endif
        viewport.minDepth = 0.0f;
        viewport.maxDepth = 1.0f;
        vkCmdSetViewport(buf, 0, 1, &viewport);

反转viewport需要将height设置为负数,但负数的高度会导致在屏幕外绘制,所以还需要设置y点移动回来。

顶点数据则使用Yup的左手坐标系,glm中摄像机矩阵使用glm::lookAtLH,而投影矩阵使用glm::perspectiveLH_ZO