Weird behavior with array uniforms for fragment shader, ideas?

Hi there,

I have a pretty simple shader sketch going but for some reason none of the array uniforms act the way I expect. I was hoping someone with some more experience than me could point out whats causing the strange behavior in this sketch. Essentially, values from a float array uniform can’t be used directly unless I convert them to a vec2. Other strangeness comes when I change the type of the array to a half as long array of vec2. In effect the body of the fragment shader’s main function contains a number of questions/cases that represent the issues I’ve found. Any help would be amazing!

link to sketch

If you want to pass a float to your shader, then, do not use an array in setUniform() method.

in draw:

ourShader.setUniform('blue', .5);

in fragment shader:

uniform float blue;
gl_FragColor = vec4(0.0,0.0,blue,1.0);

hi @ErraticGenerator,

Thanks for the general tip, fortunately that part made sense to me. Do you have any info related to the questions that are here in the comments? They are all issues stemming from the array type uniform so that’s all I’m interested in.

The uniforms are being brought in with this code also.
image

So, it looks like you want to pass an array of vectors to your shader.

When you pass a uniform to a shader, JS array becomes a GLSL vector. But if you want to pass an array of vectors, you will need to create an array of many components. But you can’t pass as 2d array, but will have to pass an 1d array with as many values as you need to create multiple vectors.

Hope my example below helps:

let vs = `
precision highp float;
varying vec4 positions;
attribute vec3 aPosition; 
void main() { 
  positions = vec4(aPosition.xyz,1.0);
  positions.xy = aPosition.xy*2.0 -1.0;
  gl_Position = positions;
}
`

let fs = `
precision highp float;
uniform vec4 particle;
uniform vec3 particle2[2];

void main() {
  gl_FragColor = vec4(particle2[0], 1.0); // red
  gl_FragColor = vec4(particle2[1], 1.0); // green
}`;

let ourShader;

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  background(100);
  ourShader = createShader(vs, fs);
  noStroke();
}

function draw() {
  ourShader.setUniform("particle", [.5, .5, random(), 1.])
  
  // 6 elements becomes 2 x vec3 in GLSL 
  ourShader.setUniform("particle2",[1., 0., 0., 0., 1., 0.])

  shader(ourShader);
  rect(0, 0, width, height)
}