问题
I've been searching the web for a while now and did not find the correct answer yet. I found the list of uniform types THREE.js uses, and I think the following code should be correct. At the last line I define an uniform array of Vector2.
uniforms: {
"center": { type: "v2", value: new THREE.Vector2( 0.5, 0.5 ) },
"aspectRatio": { type: "f", value: null },
"radius": { type: "f", value: 0.1 },
"pointList": { type: "v2v", value: [] },
},
In my js script I pass this array as follows. This should work too, I guess:
// Add effects
effect = new THREE.ShaderPass( THREE.MetaBalls2D );
effect.renderToScreen = true;
effect.uniforms[ 'aspectRatio' ].value = window.innerWidth/window.innerHeight;
effect.uniforms[ 'pointList' ].value = pointList //is an array of THREE.Vector2;
composer.addPass( effect );
My question now is, how do I access this uniform variable (pointList in this case) from the fragmentshader?
回答1:
You should know what is the max size that your array should be, so say you have an array:
var myVec2Array = [
new THREE.Vector2(),
new THREE.Vector2(),
new THREE.Vector2(),
...
]
you can do something along these lines, when you initialize a shader:
var myShader = new THREE.ShaderMaterial({
uniforms:{
_myVec2UniformArray:{
type:'v2v',
value:myVec2Array
}
},
vertexShader:
'#define ARRAYMAX '+ myVec2Array.length +'\n' + myVertexShader
}
In myVertexShader you would init:
uniform vec2 _myVec2UniformArray[ARRAYMAX];
You don't have to populate the array, but you can expose ARRAYMAX in js, and use it to manage the array on both ends.
回答2:
I would initialise it with some vectors just in case:
"pointList": { type: "v2v", value: [ new THREE.Vector2(), new THREE.Vector2() ] },
I think this is what you need to add to your shader:
uniform vec2 pointList[2];
Also, if you want to avoid Vector2
s you can use 2fv
as uniform type:
"pointList": { type: "2fv", value: [ 1, 0, 0, 1 ] }
来源:https://stackoverflow.com/questions/25249190/passing-an-array-of-vec2-to-shader-in-three-js