我需要处理许多只共享少量纹理的对象。手动定义和加载纹理(如another post on SO中所述)感觉不对......更是如此,因为WebGL中没有switch (index) {case:...}
语句。
所以我想传递纹理以用作顶点属性的顶点,并使用此数字作为fragement着色器中某些“纹理数组”的索引。但是OpenGL wiki on Samplers(不是WebGL的完美参考,而是我发现的那个)说:
采样器的变量只能以两种方式之一定义。它可以定义为函数参数或统一变量。
均匀sampler2D texture1;
对我来说听起来好像我没有采样器阵列。我已经阅读了几页纹理单元,但直到现在,这对我来说仍然是一个谜。
在上面引用的SO帖子中,Toji暗示了一个解决方案,但想要一个单独的问题 - 瞧!
谢谢,nobi
PS:我知道使用“纹理图集”的另一种可能性 - 如果这更有效或更简单 - 我会很高兴听到经验!答案 0 :(得分:11)
您必须使用常量值对采样器数组进行索引,以便您可以执行类似这样的操作
precision mediump float;
varying float v_textureIndex;
uniform sampler2D u_textures[4];
vec4 getSampleFromArray(sampler2D textures[4], int ndx, vec2 uv) {
vec4 color;
if (ndx == 0) {
color = texture2D(u_textures[0], uv);
} else if (ndx == 1) {
color = texture2D(u_textures[1], uv);
} else if (ndx == 2) {
color = texture2D(u_textures[2], uv);
} else /* if (ndx == 3) */ {
color = texture2D(u_textures[3], uv);
}
return color;
}
void main() {
gl_FragColor = getSampleFromArray(u_textures, int(v_textureIndex), vec2(0.5, 0.5));
}
您还需要告诉它使用哪个纹理单元
var textureLoc = gl.getUniformLocation(program, "u_textures[0]");
// Tell the shader to use texture units 0 to 3
gl.uniform1iv(textureLoc, [0, 1, 2, 3]);
上面的示例使用常量纹理坐标只是为了保持简单,但当然可以使用任何纹理坐标。
以下是一个示例: