如何将纹理数组绑定到WebGL着色器统一?

时间:2013-10-25 14:41:25

标签: textures webgl

我需要处理许多只共享少量纹理的对象。手动定义和加载纹理(如another post on SO中所述)感觉不对......更是如此,因为WebGL中没有switch (index) {case:...}语句。

所以我想传递纹理以用作顶点属性的顶点,并使用此数字作为fragement着色器中某些“纹理数组”的索引。但是OpenGL wiki on Samplers(不是WebGL的完美参考,而是我发现的那个)说:

  

采样器的变量只能以两种方式之一定义。它可以定义为函数参数或统一变量。

     

均匀sampler2D texture1;

对我来说听起来好像我没有采样器阵列。我已经阅读了几页纹理单元,但直到现在,这对我来说仍然是一个谜。

在上面引用的SO帖子中,Toji暗示了一个解决方案,但想要一个单独的问题 - 瞧!

谢谢,nobi

PS:我知道使用“纹理图集”的另一种可能性 - 如果这更有效或更简单 - 我会很高兴听到经验!

1 个答案:

答案 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]);

上面的示例使用常量纹理坐标只是为了保持简单,但当然可以使用任何纹理坐标。

以下是一个示例:

http://jsfiddle.net/greggman/dQuxT/

相关问题