在 GPU 上实例化更快吗?

Posted

技术标签:

【中文标题】在 GPU 上实例化更快吗?【英文标题】:Is instancing faster on GPU? 【发布时间】:2016-05-25 05:44:11 【问题描述】:

在 GPU 受限的应用程序中渲染实例化几何体时是否存在任何性能提升?还是全都与绘图调用有关?

将所有对象烘焙到单个 VBO 并使用单个绘制调用渲染它们不是更好吗?假设所有对象都是静态的,顶点内存就足够了。

【问题讨论】:

有一个取决于硬件的最佳顶点数,但是减少绘图调用总是一个不错的选择。 【参考方案1】:

如果实例模型足够小以完全适合 GPU 的预 T&L 缓存,那么它可以提高 GPU 的性能。但除非是这种情况,否则 GPU 将不得不为每个实例读取相同的网格数据。因此,1 个实例重复 200 次将具有与 200 个单独网格相同的带宽成本。

将所有对象烘焙到单个 VBO 并使用单个绘制调用渲染它们不是更好吗?

没有。仅仅因为它不一定能让你获得 GPU 性能,这并不意味着你应该放弃整个事情。如果实例化适合您,那么您将必须渲染相同的网格。所以这个“烘焙所有对象”将重复相同的网格数据。对于您打算绘制的每个实例一次。即使您不节省任何读取时间带宽,它仍然会极大地浪费内存。

不要忽视记忆的重要性。浪费内存可能会导致运行时性能问题,因为它会强制纹理超出 GPU 内存并导致抖动。

另外,它不太灵活。在一帧上,您可能只渲染 128 个实例。在另一个方面,您可能需要 156 个。在另一个方面,您可能只需要 5 个。按照您的方式,您必须保留足够的缓冲区存储空间来呈现最大数量的实例。使用实际实例...你不在乎。

这甚至不涉及如何获取每个实例的数据。通过实例化,您可以使用use gl_InstanceID 从某个 UBO/SSBO/纹理数组中读取数据,或者使用instanced arrays,以便在每个实例的基础上填充顶点属性。

您可以在“烘焙所有对象”中使用额外的整数属性来模拟gl_InstanceID,但现在您已将每个顶点增大了 4 个字节。模拟实例化数组是行不通的,因为这会极大地浪费内存。

【讨论】:

以上是关于在 GPU 上实例化更快吗?的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL ES之实例化渲染(Instancing)

可以在 SwiftUI Watch 项目中实例化 WKInterfaceController 吗?

同时在所有 GPU 内核上为每个 GPU 内核运行一个程序实例

c++实例化一个对象

您可以在 .NET 中从 JSON 实例化对象实例吗?

如何强制 Java 在实例化时重新加载类?