您好,欢迎来到叨叨游戏网。
搜索
您的当前位置:首页vulkan中的texture(VkImage、VkImageView、VkSampler、VkDeviceMemory)

vulkan中的texture(VkImage、VkImageView、VkSampler、VkDeviceMemory)

来源:叨叨游戏网

在Vulkan中,以下是这几个概念的简要说明以及它们之间的关系:

  1. VkImageView

    • VkImageView 是对 VkImage 的一个视图或描述。它指定了如何从底层的 VkImage 中读取数据,包括图像的格式、范围等。在Vulkan中,你通常需要使用 VkImageView 来对 VkImage 进行采样操作。
  2. VkSampler

    • VkSampler 是一个对象,用于描述纹理采样的方式。它定义了纹理采样时的过滤方式、边界模式、各向异性过滤等参数。VkSampler 通常与 VkImageView 一起用于纹理采样操作。
  3. VkDeviceMemory

    • VkDeviceMemory 用于表示 Vulkan 设备上的内存对象,它是用于存储 VkImage 或其他 Vulkan 对象数据的实际内存。在 Vulkan 中,你需要显式地为图像数据分配GPU内存,完成数据的写入(从CPU端内存到GPU),然后将该内存绑定到相应的 VkImage 对象上。

关系总结:

  • VkImage 是底层图像数据的表示,它包含像素数据和图像的元数据。
  • VkImageView 是对 VkImage 的描述,它提供了访问图像数据的视图,用于采样等操作。
  • VkSampler 描述了纹理采样的方式,包括过滤方式、边界模式等。
  • VkDeviceMemory 是分配给 VkImage 或其他 Vulkan 对象的实际内存,用于存储底层数据。

在实际使用中,通常流程是:
创建 VkImage 对象 → \to 分配相应的 VkDeviceMemory → \to 创建 VkImageViewVkSampler 以便在着色器中进行纹理采样操作。

一般在游戏引擎里,也会有个Texture2D的类,用来封装一些图像的操作和数据,如:

struct TextureSpecification
{
	ImageFormat Format = ImageFormat::RGBA;
	uint32_t Width = 1;
	uint32_t Height = 1;
	TextureWrap SamplerWrap = TextureWrap::Repeat;
	TextureFilter SamplerFilter = TextureFilter::Linear;
	
	bool GenerateMips = true;
	bool SRGB = false;
	bool Storage = false;
	bool StoreLocally = false;

	std::string DebugName;
};
class VulkanTexture2D : public Texture2D
{
public:
	VulkanTexture2D(const TextureSpecification& specification, const std::filesystem::path& filepath);
	VulkanTexture2D(const TextureSpecification& specification, Buffer data = Buffer());
	~VulkanTexture2D() override;
	
	virtual void Resize(const glm::uvec2& size) override;
	virtual void Resize(uint32_t width, uint32_t height) override;

	void Invalidate();

	virtual ImageFormat GetFormat() const override { return m_Specification.Format; }
	virtual uint32_t GetWidth() const override { return m_Specification.Width; }
	virtual uint32_t GetHeight() const override { return m_Specification.Height; }
	virtual glm::uvec2 GetSize() const override { return { m_Specification.Width, m_Specification.Height }; }

	virtual void Bind(uint32_t slot = 0) const override;

	virtual Ref<Image2D> GetImage() const override { return m_Image; }
	virtual ResourceDescriptorInfo GetDescriptorInfo() const override { return m_Image.As<VulkanImage2D>()->GetDescriptorInfo(); }
	const VkDescriptorImageInfo& GetDescriptorInfoVulkan() const { return *(VkDescriptorImageInfo*)GetDescriptorInfo(); }

	void Lock() override;
	void Unlock() override;

	Buffer GetWriteableBuffer() override;
	bool Loaded() const override { return m_ImageData; }
	const std::filesystem::path& GetPath() const override;
	uint32_t GetMipLevelCount() const override;
	virtual std::pair<uint32_t, uint32_t> GetMipSize(uint32_t mip) const override;

	void GenerateMips();

	virtual uint_t GetHash() const { return (uint_t)m_Image.As<VulkanImage2D>()->GetDescriptorInfoVulkan().imageView; }

	void CopyToHostBuffer(Buffer& buffer);
private:
	std::filesystem::path m_Path;
	TextureSpecification m_Specification;

	Buffer m_ImageData; // CPU端内存,存放图像文件中读取的数据

	Ref<Image2D> m_Image;	// Image2D也是自定义的类型看下面
};

VulkanImage2D这又是一层封装,核心内容是

  • VkImage Image = nullptr;
  • VkImageView ImageView = nullptr;
  • VkSampler Sampler = nullptr;
  • VmaAllocation MemoryAlloc = nullptr;

然后是其他的一些相关特性、操作的东西

class VulkanImage2D : public Image2D
{
public:
	VulkanImage2D(const ImageSpecification& specification);
	virtual ~VulkanImage2D() override;

	virtual void Resize(const glm::uvec2& size) override
	{
		Resize(size.x, size.y);
	}
	virtual void Resize(const uint32_t width, const uint32_t height) override
	{
		m_Specification.Width = width;
		m_Specification.Height = height;
		Invalidate();
	}
	virtual void Invalidate() override;
	virtual void Release() override;

	virtual uint32_t GetWidth() const override { return m_Specification.Width; }
	virtual uint32_t GetHeight() const override { return m_Specification.Height; }
	virtual glm::uvec2 GetSize() const override { return { m_Specification.Width, m_Specification.Height };}

	virtual float GetAspectRatio() const override { return (float)m_Specification.Width / (float)m_Specification.Height; }

	virtual ImageSpecification& GetSpecification() override { return m_Specification; }
	virtual const ImageSpecification& GetSpecification() const override { return m_Specification; }

	void RT_Invalidate();

	virtual void CreatePerLayerImageViews() override;
	void RT_CreatePerLayerImageViews();
	void RT_CreatePerSpecificLayerImageViews(const std::vector<uint32_t>& layerIndices);

	virtual VkImageView GetLayerImageView(uint32_t layer)
	{
		HZ_CORE_ASSERT(layer < m_PerLayerImageViews.size());
		return m_PerLayerImageViews[layer];
	}

	VkImageView GetMipImageView(uint32_t mip);
	VkImageView RT_GetMipImageView(uint32_t mip);

	VulkanImageInfo& GetImageInfo() { return m_Info; }
	const VulkanImageInfo& GetImageInfo() const { return m_Info; }

	virtual ResourceDescriptorInfo GetDescriptorInfo() const override { return (ResourceDescriptorInfo)&m_DescriptorImageInfo; }
	const VkDescriptorImageInfo& GetDescriptorInfoVulkan() const { return *(VkDescriptorImageInfo*)GetDescriptorInfo(); }

	virtual Buffer GetBuffer() const override { return m_ImageData; }
	virtual Buffer& GetBuffer() override { return m_ImageData; }

	virtual uint_t GetHash() const override { return (uint_t)m_Info.Image; }

	void UpdateDescriptor();

	// Debug
	static const std::map<VkImage, WeakRef<VulkanImage2D>>& GetImageRefs();

	void CopyToHostBuffer(Buffer& buffer);
private:
	ImageSpecification m_Specification;

	Buffer m_ImageData;

	VkImage Image = nullptr;
	VkImageView ImageView = nullptr;
	VkSampler Sampler = nullptr;
	VmaAllocation MemoryAlloc = nullptr;
	VkDeviceSize m_GPUAllocationSize;
	
	std::vector<VkImageView> m_PerLayerImageViews;
	std::map<uint32_t, VkImageView> m_PerMipImageViews;
	VkDescriptorImageInfo m_DescriptorImageInfo = {};
};

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.net 版权所有 湘ICP备2024080961号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务