Vulkan矩形绘制顺序小坑
裁剪坐标不同:
1. vulkan 裁剪坐标Y 朝下,所以下面矩形意义:
static std::vector<Vertex> vertices = { {{-0.5f, -0.5f,0}, {1.0f, 0.0f, 0.0f}}, // 左上角 {{0.5f, -0.5f,0}, {0.0f, 1.0f, 0.0f}}, // 右上角 {{0.5f, 0.5f,0}, {0.0f, 0.0f, 1.0f}}, // 右下角 {{-0.5f, 0.5f,0}, {1.0f, 1.0f, 1.0f}} // 左下角 };
明显看出来是顺时针方向。所以不考虑MVP矩阵时候。Pipeline光栅配置:
VkPipelineRasterizationStateCreateInfo rasterization_ST_CIO{}; rasterization_ST_CIO.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_ST_CIO.cullMode = VK_CULL_MODE_BACK_BIT; rasterization_ST_CIO.frontFace = VK_FRONT_FACE_CLOCKWISE; // 这里,必须配置顺时针。 rasterization_ST_CIO.depthClampEnable = VK_FALSE; rasterization_ST_CIO.rasterizerDiscardEnable = VK_FALSE; rasterization_ST_CIO.polygonMode = VK_POLYGON_MODE_FILL; rasterization_ST_CIO.lineWidth = 1.0f; rasterization_ST_CIO.depthBiasEnable = VK_FALSE;
glsl:
#version 460 core layout(location=0) in vec3 P; layout(location=1) in vec3 Cd; layout(location = 0) out vec3 fragColor; void main(){ gl_Position = vec4(P, 1.0); fragColor = Cd; }
此时渲染符合预期:
2.opengl裁剪坐标Y 朝上,所以按照下面的矩形定义(逆时针)才是符合人类直觉:
而且我们做模型也是按照Y朝上做。符合直觉。假设我们得模型就是这样得:
static std::vector<Vertex> vertices = { {{-0.5f, -0.5f,0}, {1.0f, 0.0f, 0.0f}}, // 左下角 {{0.5f, -0.5f,0}, {0.0f, 1.0f, 0.0f}}, // 右下角 {{0.5f, 0.5f,0}, {0.0f, 0.0f, 1.0f}}, // 右上角 {{-0.5f, 0.5f,0}, {1.0f, 1.0f, 1.0f}} // 左上角 };
顺序明显是逆时针。所以管线:
// 6. rasterization VkPipelineRasterizationStateCreateInfo rasterization_ST_CIO{}; rasterization_ST_CIO.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; rasterization_ST_CIO.cullMode = VK_CULL_MODE_BACK_BIT; rasterization_ST_CIO.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; rasterization_ST_CIO.depthClampEnable = VK_FALSE; rasterization_ST_CIO.rasterizerDiscardEnable = VK_FALSE; rasterization_ST_CIO.polygonMode = VK_POLYGON_MODE_FILL; rasterization_ST_CIO.lineWidth = 1.0f; rasterization_ST_CIO.depthBiasEnable = VK_FALSE;
glsl:
#version 460 core layout(location=0) in vec3 P; layout(location=1) in vec3 Cd; layout(location = 0) out vec3 fragColor; layout(binding = 0) uniform UniformBufferObject { mat4 model; mat4 view; mat4 proj; }ubo; void main(){ gl_Position = ubo.proj * ubo.view * ubo.model *vec4(P,1.0); fragColor = Cd; }
现在一切感觉类似OPENGL操作。然后接下来送入 MVP:
UBO1 ubo1{}; ubo1.model = 1.0f; ubo1.view = glm::lookAt(glm::vec3(0.0f, 0.0f, 2.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));// OGL ubo1.proj = glm::perspective(glm::radians(45.0f), bindSwapChainExtent->width / (float) bindSwapChainExtent->height, 0.1f, 10.0f); ubo1.proj[1][1] *= -1;
因为vulkan的裁剪坐标是Y朝下,glm是给opengl设计的。如果不加下面渲染出来就是反的(而且还看不到,因为你的FRONT是此时是逆时针):
ubo1.proj[1][1] *= -1;
相当于把在裁剪坐标Y反转了,这样就符合逆时针。刚好模型就像制作在Y朝上(逆时针)这个前提。人类直觉!
符合人类直觉的建模,以及正常显示。