OpenGL uniform sampler2D数组仅采样到1个纹理问题排查
多纹理单次绘制始终显示同一纹理的故障原因
核心问题出在2个关键逻辑错误:
- Sampler uniform赋值类型完全不匹配:
sampler2D类型的uniform接收的是整型的纹理单元编号,你使用glUniform1fv传入GLfloat浮点类型的数值属于非法调用,驱动会直接忽略这组无效传入值,u_Textures数组的所有元素都会保持默认值0,也就是全部指向0号纹理单元,自然无论顶点传入什么索引,都只会采样0号单元绑定的纹理。 - 纹理单元绑定与uniform配置不匹配:你给
u_Textures预设的单元值是{0,1,2},对应0、1、2三个纹理单元,但实际只把两个纹理绑定到了1、2号单元,0号单元始终残留着你第一次创建纹理时绑定的对象——你在Texture类构造函数里调用glBindTexture时没有手动激活纹理单元,默认操作的就是GL_TEXTURE0,这个创建的第一个纹理会一直留在0号单元没有被替换,成为所有采样操作的实际来源。
补充说明:用从顶点属性传入的动态值作为sampler数组索引在GLSL 4.50 core中是合法支持的,你确认v_texIndex传递正确的前提下,这部分逻辑没有问题。
修复方案
- 修正sampler数组的赋值代码,使用整型uniform接口传入纹理单元编号:
unsigned int loc1 = glGetUniformLocation(sh.getRendererID(), "u_Textures"); // 用GLint类型数组,调用glUniform1iv赋值 GLint texSlots[3] = { 0, 1, 2 }; glUniform1iv(loc1, 3, texSlots);
- 调整纹理绑定逻辑,按你设置的单元编号依次绑定纹理,优先从0号单元开始使用,避免0号单元残留旧纹理:
Texture tex1(path1); Texture tex2(path2); // 绑定槽位和texSlots里的编号一一对应 tex1.Bind(0); tex2.Bind(1); // 数组第三个位置如果暂时不用,可以绑定任意已创建的纹理,避免采样到未定义内容
如果确实需要从1号槽开始绑定纹理,只要把texSlots里的对应值改成你实际绑定的槽位编号即可,保证uniform里存的单元号和纹理实际绑定的槽位完全对应。
内容的提问来源于stack exchange,提问作者Adrian
相关产品推荐
相关产品推荐

