【问题标题】:Multiple UBOs without specifying binding point index explicitly没有明确指定绑定点索引的多个 UBO
【发布时间】:2020-01-04 17:18:18
【问题描述】:

我正在研究 OpenGL 统一缓冲区对象和着色器存储缓冲区。我认为这个问题对他们都适用,但让我们只关注 UBO。

教程好像在说“块索引”和“绑定点索引”是不同的东西,如果我在一个shader中有多个UBO,我需要指定绑定索引

layout(binding = 0) uniform first_buffer  {...};
layout(binding = 1) uniform second_buffer {...};

我的印象是块索引是由链接器确定的,可以从glGetUniformBlockIndex 读取,但是绑定点索引必须在布局中使用任意不同的binding=N 进行硬编码,并且对应的@ 987654327@,我觉得它很脆弱,很讨厌。

块索引和绑定点有什么区别?

我可以在布局中省略binding=N 吗?那么glBindBufferBase 会发生什么?

SSBO 都一样吗?

【问题讨论】:

标签: opengl glsl shader buffer-objects


【解决方案1】:

OpenGL 4.6 API Core Profile Specification - 7.6 Uniform Variables

命名统一块,如 OpenGL 着色语言规范中所述,将统一值存储在对应于的缓冲区对象的数据存储中 统一块。这样的块被分配一个统一的块索引。

块索引是着色器程序的活动程序资源的“句柄”。如果您有具有“相同”统一块的不同着色器程序,那么它们可能具有不同的缓冲区索引。

缓冲区绑定到着色器程序的统一块绑定点(例如,在着色器中由Binding point Layout Qualifier)。一方面,统一块(索引)与绑定点相关联,另一方面,缓冲区绑定到绑定点(glBindBufferBase)。所以一个缓冲区可以绑定到不同程序的统一块。

虽然缓冲区索引是固定的,并且在程序链接后无法更改,但绑定点是动态值,可以通过glUniformBlockBinding更改。程序链接时,绑定点初始化为0或Binding point Layout Qualifier设置的值。

Shader Storage Buffer Object 的原理相同。

相关问题是:

Difference between glBindBuffer and glBindBufferBase
Is it safe to use the block index as the binding point for UniformBufferObject, ShaderStorageBufferObjects, etc?
How do I query the alignment/stride for an SSBO struct?

【讨论】:

  • 我可以让OpenGL确定绑定点并查询它们,而不是自己指定它们吗? (比如块索引或 glGetAttribLocation?)
  • @spraff 默认情况下,每个绑定点都是 0。您必须在着色器代码 (layout(binding = ...)) 或 glUniformBlockBinding 中设置它们。
  • 这样做的理由是什么?在我看来,一旦一个程序链接起来,它的所有绑定点都可以自动确定,然后查询,这样就不会有搞砸幻数的机会。为什么不是这样?
  • @spraff 不,程序资源索引是在程序链接时设置的。但绑定点是动态的。您可以随时更改绑定点。例如,纹理单元也是绑定点。
  • @spraff 不!你读过答案和cmets吗?索引不是绑定点!这是不同的事情。单个程序中的每个统一块都有其单独的资源索引,该索引是在链接程序时设置的,您不必指定它。绑定点默认为 0,可用于将其绑定到缓冲区。它用于将链接程序中的统一块“连接”到缓冲区对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-17
  • 2013-01-08
  • 1970-01-01
  • 2011-04-10
  • 2013-03-28
相关资源
最近更新 更多