Closed orazdow closed 3 years ago
It is not inferred by the array length. The types are looked up from the uniform types when the program is compiled. It will work just fine
Example:
I must have assumed the length idea from somewhere else in the docs. I guess my real question is: if I have an array of 12 floats for example, I could declare it as a uniform array of 3 vec4s or 6 vec2s in the shader. I assume it will work both ways, but does it matter what the underlying gl.uniform...fv function is called? I had the impression that there is flexibility if the input data is an array of permissible size than declaring as different vector lengths could still work even if the gl uniform call doesn't match.
In the program I'm testing, I have a float array of length sixteen, and declares the uniform as 8 vec2s which works. So when you say the types are looked up when the program is compiled, does that referer to the the webgl api, or is that something twgl is doing. If you could point me to that part of the source I'd be interested to see. Sorry for the long question, I'm just trying to get an understanding these cases with uniforms and how they work in webg and using twgl.
twgl and webgl both take arrays of input so [1, 2, 3, 4, 5, 6]
will work as input to float[6]
, vec2[3]
and vec3[2]
uniforms. That the same in OpenGL as well. All you give those functions gl.uniform1fv
, gl.uniform2fv
, and gl.uniform3fv
is a flat array of values.
On the other hand WebGL is strict about which function you use. You can't use gl.uniform3fv(locationOfArrayOf3Vec2s, arrayOf6Float)
It will complain that you're trying to use a function for vec3s on a uniform of vec2s.
As for the code it's "open source" 😉 and not that long. I think if you looked at this list of files
https://github.com/greggman/twgl.js/tree/master/src
You'd figure out it's in this file
https://github.com/greggman/twgl.js/blob/master/src/programs.js
You could search for uniform2f
and you'd find this
Which would get you to search for floatVec2Setter
leading you here
and maybe eventually you'd arrive at this function
https://github.com/greggman/twgl.js/blob/master/src/programs.js#L881
Ah, that clears it up. What I missed looking earlier was getActiveUniform()
which I wasn't aware of. I didn't know you could query the shader program about it's uniforms.
Knowing the uniform function can't mismatch the shaders uniform type is important. Thinking the shader program might have leeway to 'interpret' input might have come from not realizing the shader can actually be queried, rather than being functional in one direction. Since it's compiled before the setting the uniforms, nothing is inferred and it can be determined from the shader. Thanks pointing that out.
In the documentation here It shows that the call to set the uniform's type is inferred by the array length. What if I wanted to pass an array of 4 vec2s to a fragment shader? It seems that twgl would interpret the array as having 2 vec4 elements. Is specifying numComponents allowed in a uniform object, ot is there some other way to do this?