首页 > 解决方案 > 在 Vulkan 中处理同一着色器的纹理的最佳方法是什么?

问题描述

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

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

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

如果我错了,这些样本是不是最好的方法?

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

更新:

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

它不是重复的

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

标签: vulkan

解决方案


你有很多选择。

最简单的机制是根据更改的频率将描述符集布局划分为多个集。每个场景改变的东西会在 set 0 中,每个对象(角色,静态网格等)改变的东西会在 set 1 中,每个对象改变的东西会在 set 2 中。管他呢。关键是那些以更高频率变化的东西进入更高编号的集合。

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

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

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


推荐阅读