How to post-processing

I am trying to add some post processing effects over the rendered image. I didn’t know how to do that, so I did some research. However, it is still not clear to me how I should do this.
Are the following steps the correct way to do it?

  • Configure framebuffer layout and the sequence of operations (including post-processing effect) in the VkRenderPass.
  • Set up input (VkImageView for 3D scene) and output (VkImageView to display on screen) attachments for post-processing effects.
  • Specify that depth information should be included in the input attachment for the post-processing effect (typically done by creating a separate VkAttachmentDescription for the depth information, and adding it to the VkSubpassDescription for the post-processing operation).
  • Create VkPipeline
  • Create VkFramebuffer used for rendering (include previous input & output attachments)
  • Create Rendering loop: Render first the 3D scene, which will put this output in the input of the post-processing framebuffer
  • Bind VkPipeline & VkFramebuffer of the post-processing effect > Issue the draw commands on a fullscreen quad or 2 triangles
  • The output image will be stored in the output attachment of the framebuffer

Is this correct? I am confused about how to create such render pass, or how to pass color image and depth image to the shader in order to post-process them. I am not sure whether this is the recommended way.
Until now, I just had one render pass with one subpass containing the depth attachment, MSAA attachment, and final color attachment. I guess I have to add a new attachment for post-processing. Or maybe create a new subpass? Or a new render pass? Some guidelines would be appreciated.

Basically the core idea of post-processing is when you have multiple render passes which use the same set of images. Earlier passes use those images as color\depth attachments to render into (layout: ColorAttachmentOptimal\DepthStencilAttachmentOptimal). And late passes use those images as input (layout: ShaderReadOnlyOptimal\DepthStencilReadOnlyOptimal).
And to make layout transition - you use subpassess…

You activate your first pass, render your scene to a set of buffers (frame buffer), subpasses take care of layout transitions.
Than you activate your post-processing pass (or passes if you have multiple) that will use your first pass frame buffer as textures (not exactly as textures, but close to this).
And you create your finall image…

I’d recommend checking those examples:

Especially this one, bloom - the easiest post-processing technique, good to start with:

Also probably worth mentioning, you can make some post-processing using only one single pass and multiple subpasses, but in this case your shaders will have access only to one\same pixel, which is basically makes impossible the major part of post-processing techniques…
But if you are interested - try searching for an article “Vulkan input attachments and sub passes”, sorry site engine doesn’t allow me to add a link.

1 Like