我目前正在opengl 4.3中使用ubos进行渲染,以将我的所有常量数据存储在gpu上。(比如材料描述、矩阵等)。
它可以工作,但是ubo的小尺寸(在我的实现中是64kb)迫使我多次切换缓冲区以减慢渲染速度,我正在寻找类似的方法来存储一些mb。
经过一点研究,我发现ssbo允许这样做,但也有一些不需要的“特性”:它们可以从着色器中编写,并且可能读起来比较慢。
有没有比ssbo更好的解决方案来为着色器提供大块数据?我觉得我缺少了一些东西,为什么UBO应该被限制在几个KB,而存在一个更灵活的解决方案,能够处理更多的数据?如果我正在寻找着色器存储缓冲区,是否有方法确保它们不被着色器修改?

最佳答案

ubo和ssbo基本上代表两种不同的硬件(通常)1。
着色器在组中执行,以便每个着色器在锁定步骤中执行。每组单独的着色器调用都可以访问一块内存。这个内存就是ubos所代表的。它相对较小(大约是千字节),但访问速度相当快。执行渲染操作时,ubo中的数据将复制到此着色器本地内存中。
ssbo表示全局内存。它们基本上是指针。这就是为什么它们通常没有存储限制(gl的最低要求是16兆字节,大多数实现返回的数字是gpu内存大小的顺序)。
它们的访问速度较慢,但这种性能是因为它们存在的位置以及它们是如何被访问的,而不是因为它们可能不是常数。全局内存是全局GPU内存,而不是本地常量内存。
如果材质球需要访问的数据超出其材质球本地内存的容量,则需要使用全局内存。即使你有办法将ssbo声明为“常量”,也无法回避这个问题。
1:存在硬件(基于GCN的AMD硬件),它没有专用的UBO存储。这个硬件实现ubo只是一个只读ssbo,所以所有ubo访问都是全局内存访问。这个硬件本质上依赖于有大的缓存来弥补性能差异,ubo的使用模式倾向于使其可行。但是仍然有很多硬件有专门的ubo存储空间,所以如果你的使用可以在这些限制范围内,你应该使用它们。

07-24 14:27