在vkCmdBindVertexBuffers vkCmdDraw中使用偏移量有什么好处?
What are the advantages of using offsets in vkCmdBindVertexBuffers vkCmdDraw?
在 vulkan 中,我有一个存储 6 个顶点的顶点缓冲区。前 3 个属于一个三角形,另外 3 个属于另一个三角形。每个顶点都有两个指定 x 和 y 位置的浮点数,另外 3 个指定 rgb。
如果我只想绘制一个三角形,似乎我可以通过将 3*5*sizeof(float) 的偏移量指定为 vkCmdBindVertexBuffers 的偏移量或将 firstVertex 指定为 3 到 vkCmdDraw 来获得相同的结果.
它们对这两种方法有什么优势吗?
(字节)偏移量允许您将顶点数据与其他类型的数据交错,这些数据可能不会在 sizeof(vertex)
处对齐。
在您描述的场景中,这两种方式的优势并不明显。在某些架构上,如果您正在执行一堆 back-to-back 绘制调用,这些调用使用来自相同 VkBuffer
的属性,则使用 firstVertex
而不是必须在每次绘制之间调用 vkCmdBindVertexBuffers
开销可能更低。
功能上的区别在于,通过偏移量,您正在更改 "vertex 0" 所在的位置,即调整顶点缓冲区的逻辑起点。如果您使用 vkCmdDrawIndexed
,索引值 0 将引用该偏移处的顶点。在顶点着色器中,VertexId
内置变量将为 0。
通过使用 firstVertex,您是说逻辑顶点缓冲区从 VkBuffer
中的偏移量 0 开始,但您想要从某个顶点开始绘制几何图形,而不是在缓冲区的开头。顶点着色器将在 [firstVertex
.. firstVertex+vertexCount-1
].
范围内看到 VertexId
值
因此,如果您有一个大的 VkBuffer
,您只需将不同的 unrelated/independent 网格附加到其中,尤其是当它们具有不同的布局时,您可能只想在绑定每个网格时使用偏移量:您实际上已经将不同的逻辑顶点缓冲区存储在单个 VkBuffer
中。或者,如果您的顶点布局具有 non-interleaved 属性(例如,位置在一个 "binding" 中,其他属性在另一个 "binding" 中)但想将它们存储在相同的 VkBuffer
中,您需要将相同的 VkBuffer
绑定为两个不同的顶点缓冲区,但具有不同的偏移量。
另一方面,例如,如果您将 dynamically-generated 网格几何体收集到每一帧的顶点缓冲区中,您可能只想绑定顶点缓冲区一次,然后使用 firstVertex
发出为每个网格绘制调用。或者,如果您需要使用 VertexId
进行某些计算(例如索引到存储缓冲区),您需要使用 firstVertex
以便每个顶点获得预期的 VertexId
值。
在 vulkan 中,我有一个存储 6 个顶点的顶点缓冲区。前 3 个属于一个三角形,另外 3 个属于另一个三角形。每个顶点都有两个指定 x 和 y 位置的浮点数,另外 3 个指定 rgb。
如果我只想绘制一个三角形,似乎我可以通过将 3*5*sizeof(float) 的偏移量指定为 vkCmdBindVertexBuffers 的偏移量或将 firstVertex 指定为 3 到 vkCmdDraw 来获得相同的结果.
它们对这两种方法有什么优势吗?
(字节)偏移量允许您将顶点数据与其他类型的数据交错,这些数据可能不会在 sizeof(vertex)
处对齐。
在您描述的场景中,这两种方式的优势并不明显。在某些架构上,如果您正在执行一堆 back-to-back 绘制调用,这些调用使用来自相同 VkBuffer
的属性,则使用 firstVertex
而不是必须在每次绘制之间调用 vkCmdBindVertexBuffers
开销可能更低。
功能上的区别在于,通过偏移量,您正在更改 "vertex 0" 所在的位置,即调整顶点缓冲区的逻辑起点。如果您使用 vkCmdDrawIndexed
,索引值 0 将引用该偏移处的顶点。在顶点着色器中,VertexId
内置变量将为 0。
通过使用 firstVertex,您是说逻辑顶点缓冲区从 VkBuffer
中的偏移量 0 开始,但您想要从某个顶点开始绘制几何图形,而不是在缓冲区的开头。顶点着色器将在 [firstVertex
.. firstVertex+vertexCount-1
].
VertexId
值
因此,如果您有一个大的 VkBuffer
,您只需将不同的 unrelated/independent 网格附加到其中,尤其是当它们具有不同的布局时,您可能只想在绑定每个网格时使用偏移量:您实际上已经将不同的逻辑顶点缓冲区存储在单个 VkBuffer
中。或者,如果您的顶点布局具有 non-interleaved 属性(例如,位置在一个 "binding" 中,其他属性在另一个 "binding" 中)但想将它们存储在相同的 VkBuffer
中,您需要将相同的 VkBuffer
绑定为两个不同的顶点缓冲区,但具有不同的偏移量。
另一方面,例如,如果您将 dynamically-generated 网格几何体收集到每一帧的顶点缓冲区中,您可能只想绑定顶点缓冲区一次,然后使用 firstVertex
发出为每个网格绘制调用。或者,如果您需要使用 VertexId
进行某些计算(例如索引到存储缓冲区),您需要使用 firstVertex
以便每个顶点获得预期的 VertexId
值。