GLSL忽略片段着色器中的统一布尔比较?
GLSL ignoring uniform bool comparison in fragment shader?
我正在尝试比较 GLSL 中的统一布尔值 (type_2d),以便输出两种采样器类型之一 - sampler2D 和 samplerCube。这纯粹用于区分立方体贴图(天空盒、反射立方体贴图数据等)和 sampler2d(反照率贴图、法线贴图等)。
我试过与整数、浮点数和布尔值进行比较,但帧缓冲区总是诉诸黑屏。
牢记,如果我在 "main" 中硬编码 bool 值,立方体贴图结果工作得很好,例如 "type_2d = false" 没有统一分配,而不是从 C++ 中解析统一值。
这里是 "GBuffer.f" 代码:
#version 420 core
layout(location = 0) out vec3 gPosition; // Position texel colour
layout(location = 1) out vec3 gNormal; // Normal texel colour
layout(location = 2) out vec4 gAlbedo; // Albedo texel colour
in vec3 _texcoord;
in vec3 _normal;
in vec3 _frag_pos;
uniform bool type_2d;
uniform sampler2D albedo; // Albedo and specular map
uniform samplerCube cubemap; // Skybox cubemap
vec4 final_colour;
void main()
{
gPosition = _frag_pos;
gNormal = normalize(_normal);
if (type_2d)
{
final_colour.rgb = texture(albedo, _texcoord.st).rgb;
final_colour.a = texture(albedo, _texcoord.st).a; // Emission
}
else
{
final_colour.rgb = texture(cubemap, _texcoord).rgb;
final_colour.a = texture(cubemap, _texcoord).a;
}
gAlbedo.rgba = final_colour;
}
为什么统一的 bool 比较在片段着色器中永远不起作用?我什至设法从 GLSL 获得了统一值,并且解析阶段似乎工作得非常好——这几乎就像 GLSL 拒绝 将其用于比较,从而返回一个 NULL 纹理样本创建黑屏效果。有什么想法吗?
出于某种奇怪的原因,我不得不设置 glActoveTexture(GL_TEXTURE1);和 glUniform1i(id, 1);用于渲染立方体贴图纹理(即使我在几何 paas 内部之前没有调用 GL_TEXTURE0)。我想由于采样器类型,立方体贴图纹理需要额外的偏移值?想不出其他原因。
在OpenGL中,单个纹理单元针对不同的纹理类型有多个绑定目标,如GL_TEXTURE_1D
、GL_TEXTURE_2D
、GL_TEXTURE_BUFFER
、GL_TEXTURE_CUBE_MAP
。所以从技术上讲,您 可以 将多个纹理绑定到一个单元。
默认情况下,GL_TEXTURE0
是活动纹理单元,所有制服都初始化为 0
,包括采样器制服。因此,如果您只是 glBindTexture()
一个 2D 纹理和一个立方体贴图,您最终会得到完全相同的结果。
然而,尽管在 GL 中完全允许同时将几种不同的纹理类型绑定到一个单元,但您可以只从 中 sample 每个单元的特定纹理目标。 OpenGL 4.6 core profile specification, Section "7.11 Samplers", page 155 明确指出:
It is not allowed to have variables of different sampler types pointing to
the same texture image unit within a program object.
This situation can only be detected at the next rendering command issued which triggers shader invocations,
and an INVALID_OPERATION
error will then be generated.
因此,即使您使用 uniform 在两条路径之间切换,从技术上讲,您的程序对象同时激活了两个采样器 uniform,如果不将它们设置为从不同的纹理单元采样,您最终会进入禁区。
我正在尝试比较 GLSL 中的统一布尔值 (type_2d),以便输出两种采样器类型之一 - sampler2D 和 samplerCube。这纯粹用于区分立方体贴图(天空盒、反射立方体贴图数据等)和 sampler2d(反照率贴图、法线贴图等)。
我试过与整数、浮点数和布尔值进行比较,但帧缓冲区总是诉诸黑屏。
牢记,如果我在 "main" 中硬编码 bool 值,立方体贴图结果工作得很好,例如 "type_2d = false" 没有统一分配,而不是从 C++ 中解析统一值。
这里是 "GBuffer.f" 代码:
#version 420 core
layout(location = 0) out vec3 gPosition; // Position texel colour
layout(location = 1) out vec3 gNormal; // Normal texel colour
layout(location = 2) out vec4 gAlbedo; // Albedo texel colour
in vec3 _texcoord;
in vec3 _normal;
in vec3 _frag_pos;
uniform bool type_2d;
uniform sampler2D albedo; // Albedo and specular map
uniform samplerCube cubemap; // Skybox cubemap
vec4 final_colour;
void main()
{
gPosition = _frag_pos;
gNormal = normalize(_normal);
if (type_2d)
{
final_colour.rgb = texture(albedo, _texcoord.st).rgb;
final_colour.a = texture(albedo, _texcoord.st).a; // Emission
}
else
{
final_colour.rgb = texture(cubemap, _texcoord).rgb;
final_colour.a = texture(cubemap, _texcoord).a;
}
gAlbedo.rgba = final_colour;
}
为什么统一的 bool 比较在片段着色器中永远不起作用?我什至设法从 GLSL 获得了统一值,并且解析阶段似乎工作得非常好——这几乎就像 GLSL 拒绝 将其用于比较,从而返回一个 NULL 纹理样本创建黑屏效果。有什么想法吗?
出于某种奇怪的原因,我不得不设置 glActoveTexture(GL_TEXTURE1);和 glUniform1i(id, 1);用于渲染立方体贴图纹理(即使我在几何 paas 内部之前没有调用 GL_TEXTURE0)。我想由于采样器类型,立方体贴图纹理需要额外的偏移值?想不出其他原因。
在OpenGL中,单个纹理单元针对不同的纹理类型有多个绑定目标,如GL_TEXTURE_1D
、GL_TEXTURE_2D
、GL_TEXTURE_BUFFER
、GL_TEXTURE_CUBE_MAP
。所以从技术上讲,您 可以 将多个纹理绑定到一个单元。
默认情况下,GL_TEXTURE0
是活动纹理单元,所有制服都初始化为 0
,包括采样器制服。因此,如果您只是 glBindTexture()
一个 2D 纹理和一个立方体贴图,您最终会得到完全相同的结果。
然而,尽管在 GL 中完全允许同时将几种不同的纹理类型绑定到一个单元,但您可以只从 中 sample 每个单元的特定纹理目标。 OpenGL 4.6 core profile specification, Section "7.11 Samplers", page 155 明确指出:
It is not allowed to have variables of different sampler types pointing to the same texture image unit within a program object. This situation can only be detected at the next rendering command issued which triggers shader invocations, and an
INVALID_OPERATION
error will then be generated.
因此,即使您使用 uniform 在两条路径之间切换,从技术上讲,您的程序对象同时激活了两个采样器 uniform,如果不将它们设置为从不同的纹理单元采样,您最终会进入禁区。