首页 > 解决方案 > 没有明确指定绑定点索引的多个 UBO

问题描述

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

教程似乎在说“块索引”和“绑定点索引”是不同的东西,如果我在着色器中有多个UBO,我需要指定绑定索引

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

我得到的印象是块索引由链接器确定并且可以从 读取,但是绑定点索引必须在布局中glGetUniformBlockIndex以任意不同的方式进行硬编码,并且对应的,这让我觉得脆弱和令人讨厌。binding=NglBindBufferBase(GL_UNIFORM_BUFFER, N, ubo_handle)

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

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

这对 SSBO 来说都一样吗?

标签: openglglslshaderbuffer-objects

解决方案


请参阅OpenGL 4.6 API 核心配置文件规范 - 7.6 统一变量

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

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

缓冲区通过绑定点绑定到着色器程序的统一块(例如,在着色器中通过绑定点布局限定符)。一方面,统一块(索引)与绑定点相关联,另一方面,缓冲区绑定到绑定点(by glBindBufferBase)。所以一个缓冲区可以绑定到不同程序的统一块。

虽然缓冲区索引是固定的,在程序链接后无法更改,但绑定点是一个动态值,可以通过glUniformBlockBinding. 当程序链接时,绑定点由 0 或由绑定点布局限定符设置的值初始化。

这个原理对于Shader Storage Buffer Object是一样的。

相关问题是:

glBindBuffer 和 glBindBufferBase
的区别 使用块索引作为 UniformBufferObject、ShaderStorageBufferObjects 等的绑定点是否安全?
如何查询 SSBO 结构的对齐/步幅?


推荐阅读