我有一个 Sampler2D 数组,如下所示:
uniform sampler2D u_Textures[2];。我希望能够在同一个绘图调用中渲染更多纹理(在本例中为 2 个)。在我的片段着色器中,如果我将颜色输出值设置为红色之类的值,它确实会向我显示 2 个红色方块,让我相信我在绑定纹理时做错了什么。我的代码:
Texture tex1("Texture/lin.png");
tex1.Bind(0);
Texture tex2("Texture/font8.png");
tex2.Bind(1);
auto loc = glGetUniformLocation(sh.getRendererID(), "u_Textures");
GLint samplers[2] = { 0, 1 };
glUniform1iv(loc, 2, samplers);
Run Code Online (Sandbox Code Playgroud)
void Texture::Bind(unsigned int slot) const {
glActiveTexture(slot + GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_RendererID);
}
Run Code Online (Sandbox Code Playgroud)
这是我的片段着色器:
#version 450 core
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;
in float v_texIndex;
uniform sampler2D u_Textures[2];
void main()
{
int index = int(v_texIndex);
vec4 texColor = texture(u_Textures[index], v_TexCoord);
if (texColor.a == 0.0) {
// this line fills the a = 0.0f pixels with the color red
color = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
else color = texColor;
}
Run Code Online (Sandbox Code Playgroud)
另外,它只在屏幕上绘制 tex2 纹理。这是我的 vertice 属性:
float pos[24 * 2] = {
// position xy z texture coordinate, texture index
-2.0f, -1.5f, 0.0f, 0.0f, 0.0f, 0.0f,
-1.5f, -1.5f, 0.0f, 1.0f, 0.0f, 0.0f,
-1.5f, -2.0f, 0.0f, 1.0f, 1.0f, 0.0f, // right side bottom
-2.0f, -2.0f, 0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 0.0f, 0.0f, 1.0f,
1.5f, 0.5f, 0.0f, 1.0f, 0.0f, 1.0f,
1.5f, 1.5f, 0.0f, 1.0f, 1.0f, 1.0f,
0.5f, 1.5f, 0.0f, 0.0f, 1.0f, 1.0f
};
Run Code Online (Sandbox Code Playgroud)
无论我如何更改纹理索引,它都只绘制这 2 个纹理中的 1 个。
您不能使用片段着色器输入变量来索引纹理采样器数组。您必须使用sampler2DArray( ) 而不是( )GL_TEXTURE_2D_ARRAY数组。sampler2DGL_TEXTURE_2D
Run Code Online (Sandbox Code Playgroud)int index = int(v_texIndex); vec4 texColor = texture(u_Textures[index], v_TexCoord);
是未定义的行为,因为v_texIndex是片段着色器输入变量,因此不是动态统一表达式。请参阅GLSL 4.60 规范 - 4.1.7。不透明类型
[...] 纹理组合采样器类型是不透明类型,[...]。当在着色器中聚合到数组中时,它们只能使用动态统一积分表达式进行索引,否则结果是未定义的。
使用示例sampler2DArray:
#version 450 core
layout(location = 0) out vec4 color;
in vec2 v_TexCoord;
in float v_texIndex;
uniform sampler2DArray u_Textures;
void main()
{
color = texture(u_Textures, vec3(v_TexCoord.xy, v_texIndex));
}
Run Code Online (Sandbox Code Playgroud)
texture对于所有采样器类型都是重载的。纹理坐标和纹理层不需要动态统一,但采样器数组的索引必须动态统一。
需要明确的是,问题不在于采样器数组(问题不在于sampler2D u_Textures[2];)。问题是索引。问题是v_texIndex不是动态统一的(问题是in float v_texIndex;)。当索引动态统一时它起作用(例如uniform float v_texIndex;将起作用)。而且规范只是说结果是未定义的。所以可能有一些系统可以工作。
| 归档时间: |
|
| 查看次数: |
4195 次 |
| 最近记录: |