具有不同格式顶点的顶点缓冲区

Vertex buffer with vertices of different formats

我想绘制一个由多个网格组成的模型,其中每个网格都有不同的顶点格式。是否可以将所有不同的顶点放在同一个顶点缓冲区中,并在 vkCmdBindVertexBuffers 时间指向正确的偏移量? 或者缓冲区中的所有顶点都必须具有相同的格式,因此需要为这样的模型使用多个 vbufs?

查看 vkCmdBindVertexBuffers 的手册,不清楚偏移是以字节为单位还是以顶点步幅为单位。

https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdBindVertexBuffers.html

你的问题真的分为3个问题

  1. vkCmdBindVertexBufferspOffsets 参数是否接受字节或顶点跨度?
  2. 我可以将一种以上的顶点格式放入一个顶点缓冲区吗?
  3. 我应该我将不止一种顶点格式放入一个顶点缓冲区吗?

短版是

  1. 字节
  2. 可能不会

vkCmdBindVertexBuffersoffsets 参数是否接受字节或顶点跨度?

函数签名是

void vkCmdBindVertexBuffers(
    VkCommandBuffer                             commandBuffer,
    uint32_t                                    firstBinding,
    uint32_t                                    bindingCount,
    const VkBuffer*                             pBuffers,
    const VkDeviceSize*                         pOffsets);

请注意 pOffsetsVkDeviceSize 类型。这明确表示“字节”,而不是步幅。任何 VkDeviceSize 表示原始内存中的偏移量或大小。 Vertex Strides 不是原始内存,它们只是一个计数,因此类型必须是 uint32_t 或 uint64_t.

此外,该函数签名中没有任何内容指定顶点格式,因此无法将顶点步幅计数转换为实际内存大小。请记住,与 OpenGL 不同,Vulkan 不是状态机,因此此函数没有您之前可能绑定的渲染管道的任何“内存”。

我可以将一种以上的顶点格式放入一个顶点缓冲区吗?

根据上述回答,是的。您几乎可以将任何您想要的内容放入顶点缓冲区,尽管我相信某些硬件会对顶点缓冲区的有效偏移量有对齐限制,因此请务必检查一下。

我应该我将不止一种顶点格式放入一个顶点缓冲区吗?

一般来说,您希望在尽可能少的绘制调用中渲染场景,而拥有大量任意顶点格式与此背道而驰。我会争辩说,如果可能的话,您唯一想要更改顶点格式的时间是当您切换到不同的渲染过程时,例如在渲染不透明项目与渲染透明项目之间切换时。

相反,您应该尝试将格式规范化作为资产管道的一部分,获取源资产并将它们转换为单一一致的格式。如果那不可能,那么您可以考虑在加载时进行规范化。这增加了加载代码的复杂性,但应该会大大降低渲染代码的复杂性,因为您现在只需要考虑单个顶点格式。