OpenGL 中的独特位置和绑定

问题描述 投票:0回答:1

我一直在使用 OpenGL,对绑定、位置及其索引有点困惑。

我的想法是,位置主要用于可以轻松传递的基元,而绑定则用于更复杂的结构。因此,我们使用着色器阶段之间的输入和输出数据位置(认为顶点 -> 片段着色器)以及原始制服。另一方面,绑定用于 UBO 和纹理。

现在奇怪的部分来了,输入数据、输出数据和制服的位置是唯一的,这意味着,每当我想在数据中指定时,我可以从 0 开始索引,我可以对输出数据执行相同的操作,到目前为止,这使得感觉。不过我也可以从 0 开始穿制服,这对我来说有点尴尬。

绑定也会发生同样的事情。 UBO 从 0 开始绑定,纹理也是如此,这也是合理的。然后当涉及到动态存储时,我可以再次从0开始计数,并且我没有覆盖任何东西。

我的主要问题是,存在哪些类型的不同且独特的绑定和位置?这可能与 GPU 硬件有关?

我还没有真正找到关于这个主题的很好的解释,我知道 Khronos 文档 存在,但我认为该文档对我来说不够详尽。

到目前为止我已经找到了这些类别:

地点:

  • 数据中
  • 输出数据
  • 原始制服

绑定:

  • UBO
  • 纹理(采样器)
  • 动态存储

这是我的顶点着色器的布局,其中大部分内容是我通过使用 RenderDoc 一起尝试得出的。

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 texture_coordinate;

layout(location = 0) out vec3 fs_position;
layout(location = 1) out vec3 fs_normal;
layout(location = 2) out vec2 fs_texture_coordinate;

layout(location = 0) uniform bool use_texture;

layout(binding = 0, std140) uniform Camera {
  mat4 projection;
  mat4 view;
  vec3 position;
} camera;

layout(binding = 1, std140) uniform Object {
  mat4 model_matrix;
  vec4 ambient_color;
  vec4 diffuse_color;
  vec4 specular_color;
} object;

struct Light {
  vec4 position;
  vec4 ambient_color;
  vec4 diffuse_color;
  vec4 specular_color;
};

layout(binding = 0, std430) buffer Lights {
  Light lights[];
};

layout(binding = 0) uniform sampler2D albedo_texture;

RenderDoc 展示了各种插槽,这就是我计算出大部分内容的方式。

opengl graphics glsl
1个回答
0
投票

位置和绑定不是一回事。位置指定着色器元素在着色器内的“索引”。绑定指定哪个 OpenGL 对象连接到该元素。仅支持缓冲区支持的对象(UBO、SSBO、纹理...)的绑定,但它们仍然有一个位置。

以取样员制服为例。您可以使用它的位置并从应用程序代码中设置纹理,也可以使用绑定并直接在着色器中设置它。

位置示例:

//Shader
layout(location = 1) uniform sampler2D albedo_texture;

//Client code
glActiveTexture(GL_TEXTURE2);
glBindTexture(myTexture);
glUniform1i(1, 2); //Bind sampler at location 1 to texture unit 2

绑定示例

//Shader
layout(binding = 2) uniform sampler2D albedo_texture;

//Client code
glActiveTexture(GL_TEXTURE2);
glBindTexture(myTexture);
//glUniform1i is not needed because the sampler is attached to texture unit 2 in the layout qualifier

独特的地点

位置在其元素组中必须是唯一的。对于每个着色器对象,输入和输出都有一组唯一的数字。制服必须为整个着色器程序提供独特的位置。

请注意,未分配显式位置的项目(例如问题中的采样器和 SSBO 接口块)会在着色器编译/链接期间分配唯一的 id。

绑定永远不必是唯一的。如果您希望两个采样器从同一纹理单元读取数据,那么这完全没问题。唯一的要求是绑定与客户端绑定的数据匹配。

© www.soinside.com 2019 - 2024. All rights reserved.