存储动画顶点数据的最佳方式
Best way to store animated vertex data
据我所知,有几种方法可以将顶点数据存储和传输到 GPU。
- 使用临时暂存缓冲区并将其每帧复制到独立的 GPU 内存
- 使用共享缓冲区(这很慢?)并且每帧只更新共享缓冲区
- 永久存储每个网格的暂存缓冲区,而不是每帧重新创建它并将其复制到 GPU
哪种方法最适合存储快速变化的动画网格数据?
这取决于硬件及其宣传的内存类型。请注意,以下所有内容都需要您使用 vkGetBufferMemoryRequirements
检查内存类型是否可以支持您需要的用法。
如果硬件宣传的内存类型是DEVICE_LOCAL
和HOST_VISIBLE
,那么您应该使用而不是 分期。现在,您仍然需要对其进行双缓冲,因为您无法写入 GPU 正在读取的数据,并且您不想与 GPU 同步,除非 GPU 延迟超过一帧。这也是您应该衡量的;您的 GPU 需求可能需要三重缓冲区,因此请灵活设计您的系统。
请注意,某些硬件有两个不同的堆,它们是 DEVICE_LOCAL
,但其中只有一个堆具有 HOST_VISIBLE
内存类型。所以要注意那些情况。
如果没有这样的内存类型(或者如果内存类型不支持您需要的缓冲区使用),那么您需要对此进行分析。两个备选方案是:
- 暂存(通过可用的专用传输队列)到
DEVICE_LOCAL
内存类型,最终使用数据。
- 直接使用非
DEVICE_LOCAL
内存类型。
请注意,这两者都需要缓冲,因为您希望尽可能避免同步。通过传输队列暂存也需要信号量,因为您需要确保图形队列在传输队列完成之前不会尝试使用内存。这也意味着您需要处理第 11.7 章:如何在队列之间共享资源。
不过就我个人而言,我会尽可能避免 CPU 动画顶点数据。支持 Vulkan 的 GPU 完全能够自行制作任何动画。十多年来,GPU 一直在进行骨骼加权蒙皮(甚至基于双四元数)。甚至顶点调色板动画也是 GPU 可以做的事情;总结各种不同的顶点以得出最终答案。因此,具有大量 CPU 生成的顶点数据的场景应该相对较少。
据我所知,有几种方法可以将顶点数据存储和传输到 GPU。
- 使用临时暂存缓冲区并将其每帧复制到独立的 GPU 内存
- 使用共享缓冲区(这很慢?)并且每帧只更新共享缓冲区
- 永久存储每个网格的暂存缓冲区,而不是每帧重新创建它并将其复制到 GPU
哪种方法最适合存储快速变化的动画网格数据?
这取决于硬件及其宣传的内存类型。请注意,以下所有内容都需要您使用 vkGetBufferMemoryRequirements
检查内存类型是否可以支持您需要的用法。
如果硬件宣传的内存类型是DEVICE_LOCAL
和HOST_VISIBLE
,那么您应该使用而不是 分期。现在,您仍然需要对其进行双缓冲,因为您无法写入 GPU 正在读取的数据,并且您不想与 GPU 同步,除非 GPU 延迟超过一帧。这也是您应该衡量的;您的 GPU 需求可能需要三重缓冲区,因此请灵活设计您的系统。
请注意,某些硬件有两个不同的堆,它们是 DEVICE_LOCAL
,但其中只有一个堆具有 HOST_VISIBLE
内存类型。所以要注意那些情况。
如果没有这样的内存类型(或者如果内存类型不支持您需要的缓冲区使用),那么您需要对此进行分析。两个备选方案是:
- 暂存(通过可用的专用传输队列)到
DEVICE_LOCAL
内存类型,最终使用数据。 - 直接使用非
DEVICE_LOCAL
内存类型。
请注意,这两者都需要缓冲,因为您希望尽可能避免同步。通过传输队列暂存也需要信号量,因为您需要确保图形队列在传输队列完成之前不会尝试使用内存。这也意味着您需要处理第 11.7 章:如何在队列之间共享资源。
不过就我个人而言,我会尽可能避免 CPU 动画顶点数据。支持 Vulkan 的 GPU 完全能够自行制作任何动画。十多年来,GPU 一直在进行骨骼加权蒙皮(甚至基于双四元数)。甚至顶点调色板动画也是 GPU 可以做的事情;总结各种不同的顶点以得出最终答案。因此,具有大量 CPU 生成的顶点数据的场景应该相对较少。