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

OpenGL sampler2D数组同drawcall绑定多纹理仅显示单纹理问题

问题根因

你之前怀疑的纹理绑定环节不存在问题,Texture::Bind实现、sampler uniform的赋值逻辑都是正确的。核心问题出在GLSL对sampler数组的索引限制:

  • 你在片元着色器中使用顶点插值得到的逐片元变量v_texIndex作为u_Textures数组的下标,在OpenGL 4.5桌面端标准实现中,sampler类型数组的索引必须为动态均匀表达式——即同一并行执行组内的所有片元着色器调用必须使用相同的索引值,否则会触发未定义行为,这就是你无论怎么修改索引值都只能渲染出单张纹理的根本原因。
  • 快速验证方法:把片元着色器里的索引硬编码为0或1测试,如果硬编码0时正常显示tex1、硬编码1时正常显示tex2,即可完全确认问题来源。
解决方案

根据你的硬件兼容需求选以下任意一种方案即可:

方案1:使用无绑定纹理(Bindless Texture)

这是最匹配你单次draw call逐片元切换纹理需求的方案,2016年之后发布的独立显卡基本都支持GL_ARB_bindless_texture扩展:

  1. 纹理创建完成后获取每个纹理的64位全局句柄,将句柄标记为常驻后上传到着色器uniform数组
  2. 开启bindless扩展后,sampler数组不再要求索引为动态均匀表达式,可以直接用逐片元的插值变量作为索引
    核心代码修改:
// 片元着色器
#version 450 core
#extension GL_ARB_bindless_texture : require
layout(location = 0) out vec4 color;

in vec2 v_TexCoord;
in float v_texIndex;

layout(bindless_sampler) uniform sampler2D u_Textures[2];

void main() 
{
    int index = int(v_texIndex);
    vec4 texColor = texture(u_Textures[index], v_TexCoord);
    color = texColor.a < 0.01 ? vec4(1.0f, 0.0f, 0.0f, 1.0f) : texColor;
}
// C++侧纹理上传逻辑
GLuint64 texHandles[2];
texHandles[0] = glGetTextureHandleARB(tex1.getRendererID());
glMakeTextureHandleResidentARB(texHandles[0]);
texHandles[1] = glGetTextureHandleARB(tex2.getRendererID());
glMakeTextureHandleResidentARB(texHandles[1]);

auto loc = glGetUniformLocation(sh.getRendererID(), "u_Textures");
glUniformHandleui64vARB(loc, 2, texHandles);

方案2:使用2D纹理数组替代sampler2D数组

该方案不需要依赖扩展,兼容性更好:

  • 将两张纹理上传为GL_TEXTURE_2D_ARRAY的两个独立层,要求两张纹理的尺寸、内部格式完全一致
  • 采样时将纹理索引作为第三维坐标传入采样函数即可,不存在动态索引限制,示例:
uniform sampler2DArray u_TexArray;
// 采样代码
vec4 texColor = texture(u_TexArray, vec3(v_TexCoord, v_texIndex));

方案3:按纹理拆分绘制批次

如果不需要严格控制单次draw call,直接将使用不同纹理的顶点拆分到两次绘制调用中,每次绘制前绑定对应的纹理即可,不需要在片元着色器中维护sampler数组。

额外排查项:如果硬编码索引后依然只能显示单张纹理,检查顶点属性指针的配置,确认v_texIndex对应的属性步长、偏移、数据类型设置正确,没有出现所有顶点的索引值都被解析为1的情况。

内容的提问来源于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 05:27:20