AlgebraMaster

Modern C++ 创造非凡 . 改变世界

导航

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朝上(逆时针)这个前提。人类直觉!

符合人类直觉的建模,以及正常显示。

 

posted on 2024-06-02 16:49  gearslogy  阅读(25)  评论(0编辑  收藏  举报