具有不同格式顶点的顶点缓冲区
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个问题
vkCmdBindVertexBuffers
的 pOffsets
参数是否接受字节或顶点跨度?
- 我可以将一种以上的顶点格式放入一个顶点缓冲区吗?
- 我应该我将不止一种顶点格式放入一个顶点缓冲区吗?
短版是
- 字节
- 是
- 可能不会
vkCmdBindVertexBuffers
的 offsets
参数是否接受字节或顶点跨度?
函数签名是
void vkCmdBindVertexBuffers(
VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets);
请注意 pOffsets
的 VkDeviceSize
类型。这明确表示“字节”,而不是步幅。任何 VkDeviceSize
表示原始内存中的偏移量或大小。 Vertex Strides 不是原始内存,它们只是一个计数,因此类型必须是 uint32_t 或 uint64_t.
此外,该函数签名中没有任何内容指定顶点格式,因此无法将顶点步幅计数转换为实际内存大小。请记住,与 OpenGL 不同,Vulkan 不是状态机,因此此函数没有您之前可能绑定的渲染管道的任何“内存”。
我可以将一种以上的顶点格式放入一个顶点缓冲区吗?
根据上述回答,是的。您几乎可以将任何您想要的内容放入顶点缓冲区,尽管我相信某些硬件会对顶点缓冲区的有效偏移量有对齐限制,因此请务必检查一下。
我应该我将不止一种顶点格式放入一个顶点缓冲区吗?
一般来说,您希望在尽可能少的绘制调用中渲染场景,而拥有大量任意顶点格式与此背道而驰。我会争辩说,如果可能的话,您唯一想要更改顶点格式的时间是当您切换到不同的渲染过程时,例如在渲染不透明项目与渲染透明项目之间切换时。
相反,您应该尝试将格式规范化作为资产管道的一部分,获取源资产并将它们转换为单一一致的格式。如果那不可能,那么您可以考虑在加载时进行规范化。这增加了加载代码的复杂性,但应该会大大降低渲染代码的复杂性,因为您现在只需要考虑单个顶点格式。
我想绘制一个由多个网格组成的模型,其中每个网格都有不同的顶点格式。是否可以将所有不同的顶点放在同一个顶点缓冲区中,并在 vkCmdBindVertexBuffers
时间指向正确的偏移量?
或者缓冲区中的所有顶点都必须具有相同的格式,因此需要为这样的模型使用多个 vbufs?
查看 vkCmdBindVertexBuffers
的手册,不清楚偏移是以字节为单位还是以顶点步幅为单位。
https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkCmdBindVertexBuffers.html
你的问题真的分为3个问题
vkCmdBindVertexBuffers
的pOffsets
参数是否接受字节或顶点跨度?- 我可以将一种以上的顶点格式放入一个顶点缓冲区吗?
- 我应该我将不止一种顶点格式放入一个顶点缓冲区吗?
短版是
- 字节
- 是
- 可能不会
vkCmdBindVertexBuffers
的 offsets
参数是否接受字节或顶点跨度?
函数签名是
void vkCmdBindVertexBuffers(
VkCommandBuffer commandBuffer,
uint32_t firstBinding,
uint32_t bindingCount,
const VkBuffer* pBuffers,
const VkDeviceSize* pOffsets);
请注意 pOffsets
的 VkDeviceSize
类型。这明确表示“字节”,而不是步幅。任何 VkDeviceSize
表示原始内存中的偏移量或大小。 Vertex Strides 不是原始内存,它们只是一个计数,因此类型必须是 uint32_t 或 uint64_t.
此外,该函数签名中没有任何内容指定顶点格式,因此无法将顶点步幅计数转换为实际内存大小。请记住,与 OpenGL 不同,Vulkan 不是状态机,因此此函数没有您之前可能绑定的渲染管道的任何“内存”。
我可以将一种以上的顶点格式放入一个顶点缓冲区吗?
根据上述回答,是的。您几乎可以将任何您想要的内容放入顶点缓冲区,尽管我相信某些硬件会对顶点缓冲区的有效偏移量有对齐限制,因此请务必检查一下。
我应该我将不止一种顶点格式放入一个顶点缓冲区吗?
一般来说,您希望在尽可能少的绘制调用中渲染场景,而拥有大量任意顶点格式与此背道而驰。我会争辩说,如果可能的话,您唯一想要更改顶点格式的时间是当您切换到不同的渲染过程时,例如在渲染不透明项目与渲染透明项目之间切换时。
相反,您应该尝试将格式规范化作为资产管道的一部分,获取源资产并将它们转换为单一一致的格式。如果那不可能,那么您可以考虑在加载时进行规范化。这增加了加载代码的复杂性,但应该会大大降低渲染代码的复杂性,因为您现在只需要考虑单个顶点格式。