3d 在Vulkan中使用纹理绘制多个对象
我想用多个对象绘制一个场景,每个对象都有自己的统一缓冲区和纹理,目前我可以使用动态统一缓冲区绘制多个对象,我这样做的方式是在命令缓冲区录制过程中迭代动态统一缓冲区对象偏移和顶点索引,通过这种方式,我告诉Vulkan使用特定的全局矩阵绘制模型,但是我不知道如何在此操作期间绑定纹理信息,以便Vulkan知道如何为该对象使用适当的纹理,在我的示例中,我有四个具有四种不同纹理的框。您可以使用vkCmdBindDescriptorSets绑定新纹理 确保具有纹理绑定的描述符集是布局中编号最高的描述符集3d 在Vulkan中使用纹理绘制多个对象,3d,game-engine,vulkan,3d,Game Engine,Vulkan,我想用多个对象绘制一个场景,每个对象都有自己的统一缓冲区和纹理,目前我可以使用动态统一缓冲区绘制多个对象,我这样做的方式是在命令缓冲区录制过程中迭代动态统一缓冲区对象偏移和顶点索引,通过这种方式,我告诉Vulkan使用特定的全局矩阵绘制模型,但是我不知道如何在此操作期间绑定纹理信息,以便Vulkan知道如何为该对象使用适当的纹理,在我的示例中,我有四个具有四种不同纹理的框。您可以使用vkCmdBindDescriptorSets绑定新纹理 确保具有纹理绑定的描述符集是布局中编号最高的描述符集 当
当您使用firstset>0调用VKCMDBindDescriptorSet时,绑定描述符集索引
[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];
}
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];
}
(uint32_t j=0;j
{
uint32_t dynamicofset=j*256;
VKCMDBindDescriptorSet(commandBuffers[i]、VK_PIPELINE_BIND_POINT_图形、pipelineLayout、0、1和描述符集、1和dynamicOffset);
vkCmdDraw(命令缓冲区[i],m.vertexCount[j],1,vertexCount,0);
vertexCount+=m.vertexCount[j];
}
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];
}
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];
}
(uint32_t j=0;j
{
VkDescriptorSet finalSet=描述符集[j];
VKCMDBindDescriptorSet(commandBuffers[i]、VK_PIPELINE_BIND_POINT_图形、pipelineLayout、0、1和finalSet、0、nullptr);
vkCmdDraw(命令缓冲区[i],m.vertexCount[j],1,vertexCount,0);
vertexCount+=m.vertexCount[j];
}
还有一种方法涉及使用推送常量,在这种方法中,您将所有模型的UBO数据排列到一个数组中,并为该UBO数组创建和绑定一个描述符集,从顶点着色器为传入的UBO数据定义一个数组变量,然后在绘图操作期间,使用推送常量发送单个数组索引。但是,我还没有测试过这种方法。在我的程序示例中,我将每个对象的顶点信息记录在一个压缩数组中,并跟踪另一个数组中的顶点数,当我记录绘制命令时,我使用迭代指定特定的顶点数组和统一缓冲区(选择动态均匀偏移以及顶点数组索引的),如何告诉vulkan使用正确的纹理对场景中的不同对象进行采样?假设我有4个对象和4个纹理进行采样。@BulBul:这与您提出的问题非常不同。您需要在实际问题中输入这些信息。而且,更改动态均匀偏移需要调用
vkCmdBindDescriptorSets
,为什么不应用适当的纹理描述符呢?@Nicol Bolas我编辑了我的问题,请告诉我是否足够清楚,到目前为止,我使用的是试错策略,上次我尝试使用vkCmdBindDescriptorSets使用普通统一缓冲区对象绘制多个对象(对于每个对象,我绑定了统一缓冲区的不同描述符),我所有的3D模型最终都使用了最后一个绑定的统一缓冲区集。这是一个混乱,所以这种方法对纹理有效吗?@BulBul在收到答案后移动目标帖子是一种糟糕的形式。相反,使用新的信息来提出一个更直接的问题。@ratchet freak帖子在技术上是一样的,我只是删除了一些部分hat可能会导致混淆,并添加更多细节“缺点:效率低下”-这是什么?