在Vulkan中使用纹理绘制多个对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Vulkan中使用纹理绘制多个对象相关的知识,希望对你有一定的参考价值。

我想绘制一个具有多个对象的场景,每个对象都有自己的统一缓冲区和纹理,目前我能够使用动态统一缓冲区绘制多个对象,我这样做是因为我遍历动态统一缓冲区对象的偏移量和索引在命令缓冲区记录期间的顶点,这样我告诉Vulkan使用特定的全局矩阵绘制模型,但是我不知道如何在此操作期间绑定纹理信息,以便Vulkan知道为该对象使用适当的纹理,在我的例子中,我有四个盒子,有四种不同的纹理。

答案

您可以使用vkCmdBindDescriptorSets绑定新纹理。

确保使用纹理绑定设置的描述符是布局中编号最大的集合。

当您使用firstset> 0调用vkCmdBindDescriptorSets时,绑定描述符集索引[0 ... firstSet-1]将保持不变。

另一答案

到目前为止,我设法使用以下方法绘制多个对象: -

注意:所有模型的所有顶点属性信息都存储在一个缓冲区中,该缓冲区按每个模型组织。

1.使用两个绑定的一个描述符集(一个用于UBO和一个用于纹理采样器),UBO的类型是动态的,以容纳所有对象的UBO,在命令缓冲区记录过程中,您只需迭代通过动态UBO数组对应到要绘制的指定顶点属性

专业人士:它高效快捷

缺点:所有对象都具有相同的纹理(适合使用不同的ubo多次渲染相同的模型)

绘图过程

for (uint32_t j = 0; j < m.geometryCount; j++)
    {
        uint32_t dynamicOffset =  j * 256;

        vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 1, &dynamicOffset);
        vkCmdDraw(commandBuffers[i], m.vertexCount[j], 1, vertexCount, 0);

        vertexCount += m.vertexCount[j];
    }
  1. 使用(n)个(n)个模型的描述符集的数量,每个描述符集有两个绑定(一个用于UBO,一个用于纹理采样器),在记录命令缓冲区的过程中你只需绑定对应的描述符集要绘制的指定顶点属性

优点:现在每个模型都有它的个人UBO和纹理

缺点:效率低下

绘图过程

for (uint32_t j = 0; j < m.geometryCount; j++)
    {

        VkDescriptorSet finalSet = descriptorSet[j];
        vkCmdBindDescriptorSets(commandBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &finalSet , 0, nullptr);
        vkCmdDraw(commandBuffers[i], m.vertexCount[j], 1, vertexCount, 0);

        vertexCount += m.vertexCount[j];
    }

还有另一种方法涉及使用推式常量,在这种方法中,您将所有模型的UBO数据排列到一个数组中,并为该UBO数组创建并绑定单个描述符集,从顶点着色器定义一个数组变量传入的UBO数据,然后在绘图操作期间使用推送常量发送单个数组索引。但是我还没有测试过这种方法。

以上是关于在Vulkan中使用纹理绘制多个对象的主要内容,如果未能解决你的问题,请参考以下文章

在片段着色器中丢失纹理定义

使用 Vulkan 渲染 Qml

OpenGL着色器 - 重叠多个纹理

opengl 多个对象,纹理和非纹理,伪影

WebGL入门(四十)-通过切换着色器实现一个页面同时展示多个立方体

Vulkan多线程渲染