目录
Vulkan Framebuffer
Vulkan
帧缓冲区(FrameBuffer
) 是一个容器对象(资源管理类的对象),包含了一组图像视图(Image View),用于在渲染通道中作为附件进行渲染
每个帧缓冲区的附件和渲染通道的附件描述相对应,它们共同定义了渲染的目标
帧缓存(VkFramebuffer
)在 Vulkan
中的概念类似于 OpenGL
中的帧缓存对象 FBO
每个帧缓存区包含一组图像视图,这些图像视图表示实际的图像资源,可以是颜色附件,深度附件或者模板附件,帧缓冲区用于将渲染输出写入到这些图像中(就是用于存储渲染通道(renderpass
输出的图像))
在 Vulkan
中,每个帧缓冲区至少需要一个颜色附件(color attachement
),这个颜色附件可以是和 Swapchain
关联的 ImageView
Vulkan tutorial:
An image view references a specific part of an image to be used, and a framebuffer references image views that are to be used for color, depth and stencil targets
创建 VkFramebuffer
帧缓冲区的创建过程通常涉及下面的步骤:
-
确定帧缓冲区需要兼容的
renderpass
,因为renderPass
定义了渲染操作的结构和执行顺序,以及需要的附件的数量、类型和格式 -
为每个
SwapChain
图像创建对应的ImageView
,因为渲染的图像最终需要显示在屏幕上,Swapchain
的ImageView
就是用来呈现到屏幕上的 -
使用
VkFrameBufferCreateInfo
结构体创建Framebuffer
,指定渲染通道,附件个数附件信息、宽度、高度和图层信息
用于创建帧缓冲区的结构体 VkFramebufferCreateInfo
定义如下:
typedef struct VkFramebufferCreateInfo {
// 必须是 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO
VkStructureType sType;
const void* pNext;
VkFramebufferCreateFlags flags;// 帧缓冲区创建标志,目前保留,必须为0
VkRenderPass renderPass;// 和帧缓冲区相关联的渲染通道
uint32_t attachmentCount;// 帧缓冲区的附件数量
const VkImageView* pAttachments;// 指向 VkImageView 的指针数组,每个指针指向一个附件
uint32_t width;// 帧缓冲区宽度
uint32_t height;// 帧缓冲区高度
uint32_t layers;// 帧缓冲区的层数(通常为 1)
} VkFramebufferCreateInfo;
VkFrameBuffer 创建示例
// 创建swapChainImageViews 作为颜色附件
swapChainImageViews.resize(swapChainImages.size());
for (size_t i = 0; i < swapChainImages.size(); i++) {
VkImageViewCreateInfo createInfo{
};
createInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
createInfo.image = swapChainImages[i];
createInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;
createInfo.format = swapChainImageFormat;
createInfo.components.r = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.g = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.b = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.components.a = VK_COMPONENT_SWIZZLE_IDENTITY;
createInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
createInfo.subresourceRange.baseMipLevel = 0;
createInfo.subresourceRange.levelCount = 1;
createInfo.subresourceRange.baseArrayLayer = 0;
createInfo.subresourceRange.layerCount = 1;