我目前正在尝试有效地渲染多个多维数据集,因此我想知道如何在Vulkan中使用此“实例渲染”。

我目前仅知道两种渲染大量(相同)对象的方法:

1)多个描述符集;

2)具有动态统一/动态偏移量的单个DescriptorSet;

在第一种情况下,浪费了很多内存,因为每个多维数据集只需要一个不同的模型矩阵,但是每个多维数据集仍然使用整个DescriptorSet:而且,因为我在每个帧上都注册了一个新的命令缓冲区,所以每个多维数据集都花了我2' Cmd的电话:

vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, descriptorSet, 0, nullptr);
vkCmdDraw(commandBuffer, numberOfVertices, 1, 0, 0);

但是,对于许多多维数据集,这将导致不小的CPU负载和内存浪费。

在第二种情况下,我只需要一个DescriptorSet,就可以将模型矩阵注册为Dynamic Uniform,并用所有模型矩阵填充它。
但是,我仍然需要(只需少量修改)对每个多维数据集进行相同的2个“Cmd”调用:
vkCmdBindDescriptorSets(commandBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, descriptorSet, 1, index);
vkCmdDraw(commandBuffer, numberOfVertices, 1, 0, 0);

和以前一样,对于许多多维数据集,尽管使用唯一的DescriptorSet节省了大量内存,但CPU负载仍然困扰着我。

因此,我听说了这种“实例化渲染”,应该以一条命令以某种方式告诉它绘制所有多维数据集,并为其提供模型矩阵的集合(可能仍然是一个缓冲区)。

如何做到这一点,从而防止我的程序通过一次调用在单个命令缓冲区中注册数千个“Cmd”?谢谢。

最佳答案

您将顶点属性之一设置为VkVertexInputBindingDescription::inputRate == VK_VERTEX_INPUT_RATE_INSTANCE。然后,您将必要的数据进行偏移并旋转到装箱中。

另一个选择是使用内置的顶点着色器变量,该变量指示正在处理的实例。您可以使用它索引到SSBO或UBO中以获取所需的数据。

08-27 13:51