I apologize for reviving an older thread, I had trouble myself sending an array to a shader. I was able to resolve my issue, posting my findings since there were a lot unanswered threads on the subject, in case it’s of help (@mvaligursky do step in if I got something wrong).
To make sure an array uniform is created:
- You need to add
[0]
to your uniform name, at the end. - Passing Float32Array and dynamic JS arrays is supported. I think the exact length of the array is what specifies the type of the array (e.g. if it’s a float[] or vec2/vec3/vec4[] @mvaligursky I would be glad if you can verify this).
- All arrays should be flattened, both Float32Array or regular dynamic arrays. The length of the array should be an exact multiple of the number of elements, so if you are storing three Vec3 items in your array, the flattened array should be like this (numbers are random), code example:
// Javascript
material.setParameter("myName[0]", [0.5, 1.0, -0.5, 0.25, 1.1, -0.35, 0.75, 1.7, -0.15]); // length 3 x 3 = 9
// GLSL uniform
uniform vec3 myName[3];
// GLSL you can now use it in your vertex/pixel shader like this
for (int i = 0; i < 3; i++){
vec3 myNameVec = myName[i];
}
If the number of the elements you pass to the array is dynamic, you still need to put a max limit of allowed elements. So declare your uniform with that limit and then you can use a uniform int myNameLength
as a pointer in your for loop to avoid iterating over unused elements:
// Javascript
material.setParameter("myNameLength", myArray.length);
// GLSL dynamically change the iteration count
uniform vec3 myName[30];
uniform int myNameLength;
for (int i = 0; i < myNameLength; i++){
vec3 myNameVec = myName[i];
}