在 Vulkan 中处理同一个着色器的纹理的最佳方式是什么?

What is the best way of dealing with textures for a same shader in Vulkan?

让我说一下场景,我们有几个具有相同着色器的网格(material 类型,例如 PBR material),但是网格之间的区别 material 是统一的用于渲染它们的缓冲区和纹理。

对于统一缓冲区,我们有一个动态统一缓冲区技术,可以为命令缓冲区中的每个绘图指定统一缓冲区偏移量,但是对于图像,直到这里我没有找到在命令缓冲区中指定图像视图的方法对于描述符集。在我到目前为止看到的所有示例代码中,对于每个网格和该网格的每个 material,它们都有一个新的管道、描述符集等。

我认为这不是最好的方法,必须有一种方法可以只为 material 类型设置一个管道和描述符等,并且只更改统一缓冲区偏移量和纹理图像视图和采样器,我说得对吗?

如果我错了,这些示例是否是最佳方式?

我应该如何为每分钟网格添加和删除的动态场景指定 VkDescriptorPoolCreateInfo.maxSets(或类似的其他限制)?

更新:

我认为可以为所有对象设置相同的管道和描述符集布局,但 VkDescriptorPoolCreateInfo.maxSets(或其他类似限制)存在问题,最佳实践仍然存在。

不重复

我正在寻找一种指定纹理的方法,比如我们可以使用动态统一缓冲区(以减少描述符集的数量)来做的事情,除了这个问题之外,还有一些补充性问题,主要是为了找到最佳实践得到一个答案的建议。

你有很多选择。

最简单的机制是根据更改频率将描述符集布局划分为多个集。随场景变化的东西在集合 0 中,随对象种类(角色、静态网格等)改变的东西在集合 1 中,随对象改变的东西在集合 2 中。管他呢。关键是变化频率更高的事物会出现在更高编号的集合中。

此纹理是针对每个对象的,因此它将位于编号最高的集合中。因此,您将为每个对象提供自己的包含该纹理的描述符集,然后在渲染时应用该描述符集。

至于 VkDescriptorPoolCreateInfo.maxSets,您可以将其设置为您认为适合您的系统的任何值。如果你 运行 退出,你总是可以创建另一个池;没有人强迫你只使用一个。

然而,这只是一种选择。您也可以 employ array textures or arrays of textures(取决于您的硬件能力)。在任何一种方法中,您都有一个不同图像的数组(作为单个图像视图或绑定到相同阵列描述符的多个视图)。您的每个对象统一数据将具有该对象的纹理索引,以便它可以从纹理数组 texture/array 中获取索引。