<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Vulkan 圖像視圖

          共 16155字,需瀏覽 33分鐘

           ·

          2024-08-09 08:16

          Vulkan 系列文章:
          1. 開篇,Vulkan 概述
          2. Vulkan 實例
          3. Vulkan 物理設(shè)備
          4. Vulkan 設(shè)備隊列
          5. Vulkan 邏輯設(shè)備
          6. Vulkan 內(nèi)存管理

          7. Vulkan 緩存

          這一系列文章,前期都將圍繞著這一張圖展開來講。
          眾所周知,Vulkan 編程的代碼量相對于 OpenGL 多了一個數(shù)量級(不用害怕,后面Vulkan封裝一下,用起來也會非常簡潔),本文避免一上去就講一大堆代碼,奉行概念先行。
          概念掌握的差不多了,再去看代碼,  這樣思路不容易卡住,大致就可以把握住整體代碼邏輯。最后在看代碼的過程中,理解和鞏固概念,這樣 Vulkan 學(xué)起來將事半功倍。
          前面有讀者提建議說,每一篇文章講的知識點太少了,其實這一系列文章主要面向的是初學(xué)者,不宜一次性寫太多的概念,每次講 1~2 個重要知識點,理解起來剛剛好,也不會因為太累而放棄“治療”。
          本期說說 Vulkan 圖像視圖 VkImageView 。

          什么是 Vulkan 圖像視圖

          Vulkan 圖像視圖(VkImageView)用于描述如何訪問 VkImage 對象以及訪問圖像的哪一部分。

          圖像視圖定義了圖像的格式和訪問方式,它允許渲染管線與圖像進行交互,無論是作為紋理、顏色附件還是深度/模板附件。

          在交換鏈中,我們需要為每個圖像創(chuàng)建一個基本的圖像視圖,以便將它們用作顏色附件。

          VkImage 作為紋理采樣時,也必須要創(chuàng)建其對應(yīng)的圖像視圖來更新描述符集 (DescriptorSet)

          創(chuàng)建圖像視圖

          我們通過函數(shù) vkCreateImageView 創(chuàng)建圖像視圖。

          1// vkCreateImageView 函數(shù)用于創(chuàng)建圖像視圖
          2VkResult vkCreateImageView(
          3    VkDevice device,                                  // Vulkan 邏輯設(shè)備的句柄,表示在哪個設(shè)備上創(chuàng)建圖像視圖
          4    const VkImageViewCreateInfo* pCreateInfo,         // 指向包含圖像視圖創(chuàng)建信息的 VkImageViewCreateInfo 結(jié)構(gòu)體的指針
          5    const VkAllocationCallbacks* pAllocator,          // 指向自定義分配函數(shù)的指針,可以為 nullptr 表示使用默認分配器
          6    VkImageView* pView                                // 指向 VkImageView 變量的指針,用于存儲創(chuàng)建的圖像視圖句柄
          7)
          ;

          其中 VkImageViewCreateInfo 是一個包含圖像視圖創(chuàng)建信息的結(jié)構(gòu)體。

           1typedef struct VkImageViewCreateInfo {
          2VkStructureType    sType;                // 結(jié)構(gòu)體的類型,對于此結(jié)構(gòu)體應(yīng)為VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO  
          3const void*        pNext;                // 指向擴展特定數(shù)據(jù)的指針,對于核心Vulkan功能,通常為NULL  
          4VkImageViewCreateFlags flags;           // 創(chuàng)建圖像視圖時使用的標(biāo)志位  
          5VkImage            image;                // 要創(chuàng)建視圖的圖像的句柄  
          6VkImageViewType    viewType;             // 圖像視圖的類型,決定了視圖是如何解釋圖像的  
          7VkFormat           format;               // 圖像數(shù)據(jù)的格式,定義了圖像數(shù)據(jù)的解釋方式  
          8VkComponentMapping components;           // 用于在創(chuàng)建視圖時重新映射圖像的顏色分量  
          9VkImageSubresourceRange subresourceRange; // 定義了圖像視圖的子資源范圍,包括mipmap級別、數(shù)組層以及深度層的范圍
          10} VkImageViewCreateInfo;

          其中 VkImageViewType、VkComponentMapping、VkImageSubresourceRange 類型的屬性重點關(guān)注下。

          VkImageViewType

          VkImageViewType 指定了圖像視圖的類型。

           1// VkImageViewType 是一個枚舉類型,指定了圖像視圖的類型。
          2typedef enum VkImageViewType {
          3    VK_IMAGE_VIEW_TYPE_1D = 0,          // 一維圖像視圖
          4    VK_IMAGE_VIEW_TYPE_2D = 1,          // 二維圖像視圖
          5    VK_IMAGE_VIEW_TYPE_3D = 2,          // 三維圖像視圖
          6    VK_IMAGE_VIEW_TYPE_CUBE = 3,        // 立方體貼圖視圖(六個面)
          7    VK_IMAGE_VIEW_TYPE_1D_ARRAY = 4,    // 一維圖像數(shù)組
          8    VK_IMAGE_VIEW_TYPE_2D_ARRAY = 5,    // 二維圖像數(shù)組
          9    VK_IMAGE_VIEW_TYPE_CUBE_ARRAY = 6   // 立方體貼圖數(shù)組(六個面 * 圖層數(shù))
          10} VkImageViewType;

          VkComponentMapping

          VkComponentMapping 用于指定如何從源圖像中的顏色分量映射到目標(biāo)圖像視圖的顏色分量。

          通過 VkComponentMapping 類型的屬性(components) 可以靈活地控制圖像視圖中每個顏色分量的來源,這對于圖像處理非常有用,例如轉(zhuǎn)換圖像格式、調(diào)整顏色通道等。

          默認情況下,我們將每個分量設(shè)置為 VK_COMPONENT_SWIZZLE_IDENTITY,這意味著它們將直接從源圖像中取值

           1// VkComponentMapping 結(jié)構(gòu)體定義了圖像視圖中每個顏色分量的來源。
          2typedef struct VkComponentMapping {
          3    VkComponentSwizzle r;  // R 分量的來源
          4    VkComponentSwizzle g;  // G 分量的來源
          5    VkComponentSwizzle b;  // B 分量的來源
          6    VkComponentSwizzle a;  // A 分量的來源
          7} VkComponentMapping;
          8
          9// VkComponentSwizzle 是一個枚舉類型,定義了分量的來源。
          10typedef enum VkComponentSwizzle {
          11    VK_COMPONENT_SWIZZLE_IDENTITY = 0,  // 使用原始分量
          12    VK_COMPONENT_SWIZZLE_ZERO = 1,      // 使用零值
          13    VK_COMPONENT_SWIZZLE_ONE = 2,       // 使用一值
          14    VK_COMPONENT_SWIZZLE_R = 100,       // 使用 R 分量
          15    VK_COMPONENT_SWIZZLE_G = 101,       // 使用 G 分量
          16    VK_COMPONENT_SWIZZLE_B = 102,       // 使用 B 分量
          17    VK_COMPONENT_SWIZZLE_A = 103        // 使用 A 分量
          18} VkComponentSwizzle;

          VkImageSubresourceRange

          VkImageSubresourceRange 允許你選擇圖像的哪些層面和 mip 級別應(yīng)該被包括在圖像視圖中。

          1// VkImageSubresourceRange 結(jié)構(gòu)體定義了圖像視圖應(yīng)覆蓋的圖像子資源范圍。
          2typedef struct VkImageSubresourceRange {
          3    VkImageAspectFlags aspectMask;  // 需要包括的圖像方面
          4    uint32_t baseMipLevel;          // mip 級別的起始級別
          5    uint32_t levelCount;            // mip 級別的數(shù)量
          6    uint32_t baseArrayLayer;        // 數(shù)組層的起始索引
          7    uint32_t layerCount;            // 數(shù)組層數(shù)量
          8} VkImageSubresourceRange;

          aspectMask 這個屬性比較難理解,它用于指定需要包括在圖像視圖中的圖像方面。

          例如,如果圖像有深度和/或模板信息,你可以選擇只包括顏色方面 (VK_IMAGE_ASPECT_COLOR_BIT),或者包括深度方面 (VK_IMAGE_ASPECT_DEPTH_BIT) 和/或模板方面 (VK_IMAGE_ASPECT_STENCIL_BIT)。

          示例代碼

           1// 定義 VkImageCreateInfo 結(jié)構(gòu)體并初始化
          2VkImageCreateInfo imageInfo = {};
          3imageInfo.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;      // 結(jié)構(gòu)體類型
          4imageInfo.pNext = nullptr;                                  // 指向擴展信息的指針
          5imageInfo.flags = 0;                                        // 圖像創(chuàng)建標(biāo)志,當(dāng)前必須為 0
          6imageInfo.imageType = VK_IMAGE_TYPE_2D;                     // 圖像類型為 2D
          7imageInfo.format = VK_FORMAT_R8G8B8A8_SRGB;                 // 圖像格式為 sRGB
          8imageInfo.extent.width = texWidth;                          // 圖像寬度
          9imageInfo.extent.height = texHeight;                        // 圖像高度
          10imageInfo.extent.depth = 1;                                 // 圖像深度(對于 2D 圖像為 1)
          11imageInfo.mipLevels = 1;                                    // MIP 級別數(shù)量
          12imageInfo.arrayLayers = 1;                                  // 圖像數(shù)組層數(shù)
          13imageInfo.samples = VK_SAMPLE_COUNT_1_BIT;                  // 多重采樣數(shù)量(1 表示不使用多重采樣)
          14imageInfo.tiling = VK_IMAGE_TILING_OPTIMAL;                 // 圖像數(shù)據(jù)的存儲方式(優(yōu)化存儲)
          15imageInfo.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT; // 圖像用途(作為傳輸目標(biāo)和采樣器)
          16imageInfo.sharingMode = VK_SHARING_MODE_EXCLUSIVE;          // 共享模式(獨占模式)
          17imageInfo.queueFamilyIndexCount = 0;                        // 使用隊列族索引的數(shù)量
          18imageInfo.pQueueFamilyIndices = &queueFamilyIndex;          // 隊列族索引的指針
          19imageInfo.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;        // 圖像的初始布局(未定義)
          20
          21VkImage textureImage; // 定義 VkImage 變量
          22// 創(chuàng)建圖像
          23if (vkCreateImage(device, &imageInfo, nullptr, &textureImage) != VK_SUCCESS) {
          24    throw std::runtime_error("failed to create texture image!"); // 如果創(chuàng)建圖像失敗,拋出異常
          25}
          26
          27// 獲取圖像的內(nèi)存需求
          28VkMemoryRequirements memRequirements;
          29vkGetImageMemoryRequirements(device, textureImage, &memRequirements);
          30
          31// 創(chuàng)建 VkMemoryAllocateInfo 結(jié)構(gòu)體并初始化
          32VkMemoryAllocateInfo allocInfo = {};
          33allocInfo.sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO; // 結(jié)構(gòu)體類型
          34allocInfo.allocationSize = memRequirements.size;          // 所需內(nèi)存大小
          35allocInfo.memoryTypeIndex = findMemoryType(memRequirements.memoryTypeBits, 
          36    VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);                 // 內(nèi)存類型索引
          37
          38VkDeviceMemory textureImageMemory; // 定義 VkDeviceMemory 變量
          39// 分配內(nèi)存
          40if (vkAllocateMemory(device, &allocInfo, nullptr, &textureImageMemory) != VK_SUCCESS) {
          41    throw std::runtime_error("failed to allocate texture image memory!"); // 如果分配內(nèi)存失敗,拋出異常
          42}
          43
          44// 將內(nèi)存綁定到圖像
          45vkBindImageMemory(device, textureImage, textureImageMemory, 0);
          46
          47// 定義 VkImageViewCreateInfo 結(jié)構(gòu)體并初始化
          48VkImageViewCreateInfo viewInfo = {};
          49viewInfo.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;  // 結(jié)構(gòu)體類型
          50viewInfo.pNext = nullptr;                                   // 指向擴展信息的指針
          51viewInfo.flags = 0;                                         // 圖像視圖創(chuàng)建標(biāo)志
          52viewInfo.image = textureImage;                              // 要創(chuàng)建視圖的圖像句柄
          53viewInfo.viewType = VK_IMAGE_VIEW_TYPE_2D;                  // 圖像視圖類型為 2D
          54viewInfo.format = VK_FORMAT_R8G8B8A8_UNORM;                  // 圖像視圖的格式
          55viewInfo.components.r = VK_COMPONENT_SWIZZLE_R;      // R 分量映射
          56viewInfo.components.g = VK_COMPONENT_SWIZZLE_G;      // G 分量映射
          57viewInfo.components.b = VK_COMPONENT_SWIZZLE_B;      // B 分量映射
          58viewInfo.components.a = VK_COMPONENT_SWIZZLE_A;      // A 分量映射
          59viewInfo.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT; // 視圖的子資源范圍(顏色部分)
          60viewInfo.subresourceRange.baseMipLevel = 0;                 // 基礎(chǔ) MIP 級別
          61viewInfo.subresourceRange.levelCount = 1;                   // MIP 級別數(shù)量
          62viewInfo.subresourceRange.baseArrayLayer = 0;               // 基礎(chǔ)數(shù)組層
          63viewInfo.subresourceRange.layerCount = 1;                   // 數(shù)組層數(shù)量
          64
          65VkImageView textureImageView; // 定義 VkImageView 變量
          66// 創(chuàng)建圖像視圖
          67if (vkCreateImageView(device, &viewInfo, nullptr, &textureImageView) != VK_SUCCESS) {
          68    throw std::runtime_error("failed to create texture image view!"); // 如果創(chuàng)建視圖失敗,拋出異常
          69}
          70
          71// Vulkan 編程...
          72
          73// 使用完成后銷毀資源
          74vkDestroyImageView(device, textureImageView, nullptr); // 銷毀圖像視圖
          75vkDestroyImage(device, textureImage, nullptr);         // 銷毀圖像
          76vkFreeMemory(device, textureImageMemory, nullptr);     // 釋放圖像內(nèi)存


          -- END --


          進技術(shù)交流群,掃碼添加我的微信:Byte-Flow



          獲取相關(guān)資料和源碼


          學(xué)習(xí)音視頻、OpenGL ES、Vulkan 、Metal、圖像濾鏡、視頻特效及相關(guān)渲染技術(shù)的付費社群,面試指導(dǎo),1v1 簡歷服務(wù),職業(yè)規(guī)劃。


          我的付費社群



          項目疑難問題解答、大廠內(nèi)部推薦、面試指導(dǎo)、簡歷指導(dǎo)、代碼指導(dǎo)、offer 選擇建議、學(xué)習(xí)路線規(guī)劃,可以點擊找我一對一解答。

          瀏覽 115
          1點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          1點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久国产乱子伦精品一区二区豆花 | 狠狠躁日日躁夜夜躁A片男男视频 | 91成人社区无码 | 少妇逼 | 欧美成人乱码视频欧美 |