10

我目前正在使用 UBO 在 OpenGL 4.3 中进行渲染,以将我所有的常量数据存储在 GPU 上。(诸如材料描述、矩阵等之类的东西)。它可以工作,但是 UBO 的小尺寸(在我的实现中为 64kB)迫使我多次切换缓冲区减慢渲染速度,我正在寻找类似的方法来存储几 MB。

经过一番研究,我发现 SSBO 完全允许这样做,但也有不需要的“功能”:它们可以从着色器中写入,并且可能读取速度较慢。

是否有比 SSBO 更好的解决方案来向着色器提供大块数据?我觉得我遗漏了一些东西,为什么 UBO 应该限制在几 kB 而存在能够处理更多数据的更灵活的解决方案?如果着色器存储缓冲区是我正在寻找的,有没有办法确保它们不被着色器修改?

4

1 回答 1

18

UBO 和 SSBO 从根本上代表两种不同的硬件(通常)1

着色器按组执行,因此每个着色器都以锁步执行。每组单独的着色器调用都可以访问一块内存。这种记忆就是 UBO 所代表的。它相对较小(大约为千字节),但访问它的速度非常快。执行渲染操作时,来自 UBO 的数据被复制到此着色器本地内存中。

SSBO 代表全局内存。它们基本上是指针。这就是为什么它们通常没有存储限制(最低 GL 要求是 16字节,大多数实现返回一个与 GPU 内存大小差不多的数字)。

它们的访问速度较慢,但​​这种性能是因为它们存在的位置和访问方式,而不是因为它们可能不是恒定的。全局内存是全局 GPU 内存而不是本地常量内存。

如果着色器需要访问的数据超出其着色器本地内存的容量,那么它需要使用全局内存。即使您有办法将 SSBO 声明为“常量”,也无法解决这个问题。

1:存在没有专用 UBO 存储的硬件(基于 GCN 的 AMD 硬件)。该硬件将 UBO 实现为只读 SSBO,因此所有 UBO 访问都是全局内存访问。这种硬件本质上依赖于拥有大缓存来弥补性能差异,而 UBO 的使用模式往往使这变得可行。但是仍然有很多硬件为 UBO 存储提供了专用空间,所以如果你的使用可以满足这些限制,你应该使用它们。

于 2015-12-03T16:39:24.033 回答