You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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传递正确的前提下,这部分逻辑没有问题。


修复方案
  1. 修正sampler数组的赋值代码,使用整型uniform接口传入纹理单元编号:
unsigned int loc1 = glGetUniformLocation(sh.getRendererID(), "u_Textures");
// 用GLint类型数组,调用glUniform1iv赋值
GLint texSlots[3] = { 0, 1, 2 };
glUniform1iv(loc1, 3, texSlots);
  1. 调整纹理绑定逻辑,按你设置的单元编号依次绑定纹理,优先从0号单元开始使用,避免0号单元残留旧纹理:
Texture tex1(path1);
Texture tex2(path2);
// 绑定槽位和texSlots里的编号一一对应
tex1.Bind(0);
tex2.Bind(1);
// 数组第三个位置如果暂时不用,可以绑定任意已创建的纹理,避免采样到未定义内容

如果确实需要从1号槽开始绑定纹理,只要把texSlots里的对应值改成你实际绑定的槽位编号即可,保证uniform里存的单元号和纹理实际绑定的槽位完全对应。


内容的提问来源于stack exchange,提问作者Adrian

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 07:21:20