Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing an array of vec2 to shader in THREE.js

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?

like image 702
ThijsM Avatar asked Dec 25 '22 05:12

ThijsM


1 Answers

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.

like image 96
pailhead Avatar answered Jan 02 '23 20:01

pailhead