Vulkan Samples 阅读 -- Basics(五): Input Attachments & Sub Passes & Offscreen Renderings

Input Attachments

prepare

  • loadAssets: 加载模型
  • prepareUniformBuffers
    • updateUniformBuffers
  • setupRenderPass: 重写了父类的方法, 创建 Attachment
    • 创建的数量是: swapChain.imageCount

    • 每个 Attachment 都需要创建 color 和 depth 附件

      • VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT
      • VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
    • 初始化每个 Attachment 的参数

    • 创建subpass: std::array<VkSubpassDescription,2> subpassDescriptions

      • VkAttachmentReference
      • 创建一个给 Attachment 填充颜色和深度的subpass
      • 创建一个swap chain 填充颜色的 subpass
      • 再创建两个引用 VkAttachmentReference inputReferences
        • 将 fragment shader 中的输出写入Attachment : InputAttachments
      • swap chain 的subpass 中引入 InputAttachments, 填充颜色
    • 创建 VkSubpassDependency

      	dependencies[0].srcSubpass = VK_SUBPASS_EXTERNAL;
      	dependencies[0].dstSubpass = 0;
      	//源为管线
      	dependencies[0].srcStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
      	//输出到 color attachment 中
      	dependencies[0].dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
      	//读取方式
      	dependencies[0].srcAccessMask = VK_ACCESS_MEMORY_READ_BIT;
      	dependencies[0].dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
      	dependencies[0].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
      
      	// This dependency transitions the input attachment from color attachment to shader read
      	dependencies[1].srcSubpass = 0;
      	dependencies[1].dstSubpass = 1;
      	//源为 color attachment
      	dependencies[1].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
      	//输出到 fragment shader 中
      	dependencies[1].dstStageMask = VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT;
      	dependencies[1].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
      	//读取方式
      	dependencies[1].dstAccessMask = VK_ACCESS_SHADER_READ_BIT;
      	dependencies[1].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
      
      	dependencies[2].srcSubpass = 0;
      	dependencies[2].dstSubpass = VK_SUBPASS_EXTERNAL;
      	//源为 color attachment 
      	dependencies[2].srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT;
      	// 输出到管线中
      	dependencies[2].dstStageMask = VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT;
      	dependencies[2].srcAccessMask = VK_ACCESS_COLOR_ATTACHMENT_READ_BIT | VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT;
      	dependencies[2].dstAccessMask = VK_ACCESS_MEMORY_READ_BIT;
      	dependencies[2].dependencyFlags = VK_DEPENDENCY_BY_REGION_BIT;
      
    • vkCreateRenderPass

  • setupDescriptors
    • 创建3个pool
      • VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
      • VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
      • VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
    • Attachment write
      • vkCreateDescriptorSetLayout
      • vkCreatePipelineLayout
      • vkAllocateDescriptorSets
      • vkUpdateDescriptorSets
    • Attachment read
      • descriptorSetLayoutBinding: 三个
        • VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 颜色
        • VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT: 深度
        • VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
      • vkCreateDescriptorSetLayout
      • vkCreatePipelineLayout
      • vkAllocateDescriptorSets
      • vkUpdateDescriptorSets
  • preparePipelines: attachment 需创建两个pipeline, 一个写 Attachment, 一个读 attachment
    • VkGraphicsPipelineCreateInfo: 多出了为Attachment配置的代码
      • pipelineCI.renderPass = renderPass;
      • Attachment write
        • pipelineCI.subpass = 0;
        • pipelineCI.layout = pipelineLayouts.attachmentWrite;
      • vkCreateGraphicsPipelines
      • Attachment read
        • pipelineCI.subpass = 1
        • pipelineCI.layout = pipelineLayouts.attachmentRead;
      • vkCreateGraphicsPipelines
  • buildCommandBuffers: 分别为两个 subpass 创建 CommandBuffer
    	/*
    	First sub pass
    		Fills the attachments
    	*/
    	{
    		vks::debugmarker::beginRegion(drawCmdBuffers[i], "Subpass 0: Writing attachments", glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
    
    		vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.attachmentWrite);
    		vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.attachmentWrite, 0, 1, &descriptorSets.attachmentWrite, 0, NULL);
    		scene.draw(drawCmdBuffers[i]);
    
    		vks::debugmarker::endRegion(drawCmdBuffers[i]);
    	}
    
    	/*
    		Second sub pass
    		Render a full screen quad, reading from the previously written attachments via input attachments
    	*/
    	{
    		vks::debugmarker::beginRegion(drawCmdBuffers[i], "Subpass 1: Reading attachments", glm::vec4(1.0f, 1.0f, 1.0f, 1.0f));
    
    		vkCmdNextSubpass(drawCmdBuffers[i], VK_SUBPASS_CONTENTS_INLINE);
    
    		vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.attachmentRead);
    		vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.attachmentRead, 0, 1, &descriptorSets.attachmentRead[i], 0, NULL);
    		vkCmdDraw(drawCmdBuffers[i], 3, 1, 0, 0);
    
    		vks::debugmarker::endRegion(drawCmdBuffers[i]);
    	}
    
    

render

  • draw
  • updateUniformBuffers

小结

   本节主要讲怎样使用 Attachments 进行渲染. 但是我觉得这里的重点是怎样使用subpass进行渲染.

Sub Passes

prepare

  • loadAssets: 加载模型和纹理
  • initLights: 设置光源
  • prepareUniformBuffers
    • updateUniformBufferDeferredMatrices
    • updateUniformBufferDeferredLights
  • setupFrameBuffer: 重写父类方法
    • 当屏幕大小发生遍布重写设置Gbuffer: createGBufferAttachments
    • writeDescriptorSets
    • vkUpdateDescriptorSets
    • 正向渲染
    • writeDescriptorSets
    • vkUpdateDescriptorSets
    • vkCreateFramebuffer
  • setupRenderPass: 重写父类方法
    • createGBufferAttachments: 创建Gbuffer
      • createAttachment – position
      • createAttachment – normal
      • createAttachment – albedo
    • VkAttachmentDescription: 有5个, 与上一节相似,主要设置,怎么写入gbuffer,怎么从gbuffer读数据
    • vkCreateRenderPass
  • setupDescriptorSetLayout
    • vkCreateDescriptorSetLayout
    • vkCreatePipelineLayout
  • preparePipelines: 中增加了 blendAttachmentStates
    • colorBlendState.attachmentCount = static_cast<uint32_t>(blendAttachmentStates.size());
    • colorBlendState.pAttachments = blendAttachmentStates.data();
  • setupDescriptorPool
    • 创建3个pool
      • VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER
      • VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER
      • VK_DESCRIPTOR_TYPE_INPUT_ATTACHMENT
  • setupDescriptorSet
    • vkAllocateDescriptorSets
    • writeDescriptorSets
  • prepareCompositionPass:
    • Descriptor set layout
      • descriptorSetLayoutBinding
        • Position input attachment
        • Normal input attachment
        • Albedo input attachment
        • Light positions
          -vkCreateDescriptorSetLayout
    • Pipeline layout
      • vkCreatePipelineLayout
    • Descriptor sets
      • vkAllocateDescriptorSets
      • writeDescriptorSets
        • writeDescriptorSet
          • Position texture target
          • Normals texture target
          • Albedo texture target
          • Fragment shader lights
            -vkUpdateDescriptorSets
    • Pipeline
      • pipelineCreateInfo
      • vkCreateGraphicsPipelines
    • Transparent (forward) pipeline
      • vkCreateDescriptorSetLayout
      • vkCreatePipelineLayout
      • vkAllocateDescriptorSets
      • vkUpdateDescriptorSets
      • vkCreateGraphicsPipelines
  • buildCommandBuffers: subpass有3个
    • 第一个将场景数据写入Gbuffer
    • 第二个用gbuffer数据渲染到attachment中
    • 第三个正向渲染

render

  • draw
  • updateUniformBufferDeferredMatrices
  • updateUniformBufferDeferredLights

小结

   本节主要讲延迟渲染的方法. 总体来说就是更详细介绍了subpass的使用方法.

Offscreen Renderings

prepare

  • loadAssets: 加载模型
  • prepareOffscreen: 准备离屏渲染资源
    • 准备的资源如下
    	struct OffscreenPass {
    		int32_t width, height;
    		VkFramebuffer frameBuffer;
    		FrameBufferAttachment color, depth;
    		VkRenderPass renderPass;
    		VkSampler sampler;
    		VkDescriptorImageInfo descriptor;
    	} offscreenPass;
    
    • vkCreateImage(color)
    • vkGetImageMemoryRequirements
    • vkAllocateMemory
    • vkBindImageMemory
    • vkCreateImageView
    • vkCreateSampler
    • vkCreateImage(depth)
    • vkGetImageMemoryRequirements
    • vkAllocateMemory
    • vkBindImageMemory
    • vkCreateImageView
    • attchmentDescriptions: 分别为color和depth
    • subpassDescription: 附加Attachment引用
    • vkCreateRenderPass
    • vkCreateFramebuffer: 将渲染后的资源写入 frame buffer
  • prepareUniformBuffers
    • updateUniformBuffers
    • updateUniformBufferOffscreen: 离屏pass更新uniform
  • setupDescriptorSetLayout
    • vkCreateDescriptorSetLayout
    • vkCreatePipelineLayout
  • preparePipelines: 新建四个pipelines
    • Render-target debug display
    • Mirror
    • Phong shading pipelines
    • Offscreen
  • setupDescriptorPool
  • setupDescriptorSet: 为三个pipeline设置
    • Mirror plane descriptor set (Mirror)
    • Shaded descriptor sets (Phong shading pipelines)
    • Offscreen
  • buildCommandBuffers: subpass有2个
    • First render pass: Offscreen rendering
    • Scene rendering with applied radial blur

render

  • draw
  • updateUniformBuffers
  • updateUniformBufferOffscreen

小结

   离屏渲染也就是将渲染结果写入 attachment中 . 是 attachment 结合 subpass的一种实用方法.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
realesrgan-ncnn-vulkan-20211212-windows是一个基于ncnn框架和Vulkan图形API开发的图像超分辨率增强模型。它是由GitHub用户realsrgan开发的最新版本,最新发布日期为2021年12月12日,专为Windows操作系统而设计。 该模型的主要应用是图像超分辨率增强,通过提高图像的分辨率和细节,使图像看起来更加清晰和真实。它采用深度学习和卷积神经网络等先进的技术,能够将低分辨率的图像转换成高分辨率的图像,从而提升图像的质量和视觉效果。 realesrgan-ncnn-vulkan-20211212-windows的开发使用了ncnn框架和Vulkan图形API,这使得它能够在Windows系统上实现快速且高效的图像处理。ncnn是一个轻量级的深度学习框架,专注于在移动平台和嵌入式设备上实现高性能和低延迟的推理。而Vulkan图形API是一种跨平台的图形渲染和计算API,可以充分利用计算设备的性能,提供高效的图像处理和渲染能力。 realesrgan-ncnn-vulkan-20211212-windows的使用可以通过命令行或者图形界面进行,用户可以根据自己的需求和偏好选择适合的方式。该模型提供了训练好的权重参数,用户可以直接加载这些参数并进行图像超分辨率增强。此外,该模型还支持批量处理和视频处理,方便用户对多个图像进行处理。 总之,realesrgan-ncnn-vulkan-20211212-windows是一个高效、快速且易于使用的图像超分辨率增强模型,适用于Windows系统,并利用了ncnn框架和Vulkan图形API的优势,为用户提供了出色的图像处理效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值