2

As mentioned here it would be possible to "bind all the textures you need to a sampler array in the shader and then index it with a vertex attribute". How would I do the binding? Currently I bind my textures like so (if that's correct in the first place; it works at least):

sampler[i] = gl.getUniformLocation(program, "u_sampler" + i);
...
for (var i = 0, len = textures.length; i < len; i++) {
    gl.activeTexture(gl.TEXTURE0 + i);
    gl.bindTexture(gl.TEXTURE_2D, textures[i]);
    gl.uniform1i(sampler[i], i);
}

To bind an array of samplers now would I throw away activeTexture and bindTexture and use something like this?

gl.uniform1iv(sampler, [0,...,len-1]);
Community
  • 1
  • 1
Mouagip
  • 5,139
  • 3
  • 37
  • 52

2 Answers2

2

Never mind, I think I found the solution. My code looks as follows:

var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(...
gl.bindTexture(gl.TEXTURE_2D, null);
textures[i] = texture;

...compose texture images...

gl.activeTexture(gl.TEXTURE0 + i);
gl.bindTexture(gl.TEXTURE_2D, textures[i]);
gl.texSubImage2D(gl.TEXTURE_2D, 0, xoffset, yoffset, gl.RGBA, gl.UNSIGNED_BYTE, image);

...fill all textures...

var sampler = gl.getUniformLocation(program, "u_sampler");
var samplerArray = new Int32Array(textures.length);
var len = samplerArray.length;
while (len--) {
    samplerArray[len] = len;
}
gl.uniform1iv(sampler, samplerArray);

Now I can access the samplers in the fragment shader via u_sampler[i] correctly.

Mouagip
  • 5,139
  • 3
  • 37
  • 52
0

If I understand the description in question you linked to correctly, the proposal is leave the API code as is and specify an array of samplers in the shader. This array would then be indexed via an attribute. Something like:

uniform sampler2D samplers[8];
uniform int index;
..
vec4 color = texture2D(samplers[index], coord);

This technique should work in OpenGL. It is, however, not supported by the WebGL specification, which states that dynamic indexing (i.e., indexing with a non-constant variable) of samplers is not supported. See the WebGL specification here.

Jan-Harald
  • 383
  • 1
  • 4
  • As far as I know indexing with a loop variable is allowed. Or is there an exception for sampler arrays? However my shader seems to work. – Mouagip Jun 13 '13 at 21:17
  • My first approach using multiple single uniform sampler and lots of if statements seems so be slightly faster, though. – Mouagip Jun 13 '13 at 21:37
  • 1
    Indexing with a loop variable is fine (generally). Indexing with non-constant global variables like in my example is not. The specification uses the term "constant-index-expression", which basically means it must be possible for the compiler to determine the sampler indices at compile-time (for example, by unrolling the loop). – Jan-Harald Jun 13 '13 at 21:49