Vulkan多管线渲染与绘制世界坐标轴Axis

一、多管线渲染

设置 vulkan 图形管线要点

vulkan API 绘制不同的拓扑类型,比如三角形、线段、点都要重新设置图形管线。可以在初始化过程中设置多套不同的管线缓存起来,然后在绘制帧的时候绑定需要的管线进行绘制,这比每次绘制的时候重新创建管线性能要好得多。如果缓存了很多管线,每次绘制一个模型实例就绑定一次某个管线,那么性能也会不好。绘制的时候应该根据不同类型的管线对模型实例进行分组绘制,每绑定一种图形管线,就把那种图形管线对应的模型实例都放到一个集合中进行批量绘制,这样总体下来性能影响可以忽略不计。

在vkinit 中创建两套管线分别用于绘制线段和三角形
  • 多个渲染管线(VkPipeline)完全可以复用同一个管线布局(VkPipelineLayout),只要它们的 descriptor set layout 和 push constant 定义一致即可,这样可以减少资源和管理复杂度,也方便切换管线。常见做法就是:
    • 用同一套 descriptor set layout 和 push constant 定义,创建一个 VkPipelineLayout。
    • 所有相关的管线(如三角形管线、线管线、不同着色器管线)都用这个 pipeline layout。
  • 不同的管线绑定不同的着色器。画线的绑定线段专用着色器,片段着色器中移除纹理采样可以提供性能;画三角形的继续使用之前带纹理采样的片段着色器。
 // 创建图形管线
 {
   
       VkPushConstantRange pushConstantRange{
   };
       pushConstantRange.stageFlags = VK_SHADER_STAGE_VERTEX_BIT;
       pushConstantRange.offset = 0;
       pushConstantRange.size = sizeof(PushConstants);

       VkPipelineLayoutCreateInfo pipelineLayoutInfo{
   };
       pipelineLayoutInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO;
       pipelineLayoutInfo.setLayoutCount = 1;
       pipelineLayoutInfo.pSetLayouts = &ctx->descriptorSetLayout;
       pipelineLayoutInfo.pushConstantRangeCount = 1;
       pipelineLayoutInfo.pPushConstantRanges = &pushConstantRange;

       if (vkCreatePipelineLayout(ctx->device, &pipelineLayoutInfo, nullptr, &ctx->pipelineLayout) != VK_SUCCESS) {
   
           throw std::runtime_error("创建管线布局失败!");
       }

       // 绘制线段的管线
       ctx->piplelineLine = createPipeline(ctx, 
           VK_PRIMITIVE_TOPOLOGY_LINE_LIST,   
           "assets/shaders/line.vert.spv", 
           "assets/shaders/line.frag.spv");

       // 绘制三角形的管线
       ctx->piplelineTriangle = createPipeline(ctx, 
           VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, 
           "assets/shaders/triangle.vert.spv", 
           "assets/shaders/triangle.frag.spv");
   }

模型按类型实例分组

VkContext 结构中添加 std::vector<MeshInstance*> lineInstances属性用于存放线段类型的网格对象,原来的std::vector<scene::MeshInstance*> meshInstances存储三角形类型的网格对象。

  • 更新 main.cpp
...
axis = new Axis();
vkcontext.lineInstances.push_back(axis);

MeshInstance* objModel = ObjModelLoader::loadModel("assets/models/viking_room.obj", "assets/models/viking_room.png");
vkcontext.meshInstances.push_back(objModel);
...

分别为lineInstancesmeshInstances创建顶点/索引缓冲

// 创建顶点缓冲
 for (MeshInstance* mesh : ctx->lineInstances) {
   
     if (mesh->vertices.empty()) continue;
     createVertexBuffer(mesh, ctx);
 }
 for (MeshInstance* mesh : ctx->meshInstances) {
   
     if (mesh->vertices.empty()) continue;
     createVertexBuffer(mesh, ctx);
 }

 // 创建索引缓冲
 for (MeshInstance* mesh : ctx->lineInstances) {
   
     if (mesh->indices.empty()) continue;
     createIndexBuffer(mesh, ctx);
 }
 for (MeshInstance* mesh : ctx-&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值