Updating ShaderMaterial attribute in three.js
glsl, javascript, three.js, vertex-shader, webgl
Solution
Turns out it is possible to update attributes like uniforms. In my case, I was missing one all important line of code:
attributes.displacement.needsUpdate = true;
The line was omitted from the tutorial and upon adding it I get the exact behavior I was hoping for.
Problem
From the three.js tutorial on shaders, we learn we can update uniform values of a ShaderMaterial: ``` var attributes = { displacement: { type: 'f', // a float value: [] // an empty array } }; var uniforms = { amplitude: { type: 'f', // a float value: 1 } }; var vShader = $('#vertexshader'); var fShader = $('#fragmentshader'); // create the final material var shaderMaterial = new THREE.MeshShaderMaterial({ uniforms: uniforms, attributes: attributes, vertexShader: vShader.text(), fragmentShader: fShader.text() }); ... var frame = 0; function update() { // update the amplitude based on // the frame value. uniforms.amplitude.value = Math.cos(frame); // update the frame counter frame += 0.1; renderer.render(scene, camera); // set up the next call requestAnimFrame(update); } ``` What isn't mentioned is whether this same behavior extends to attributes. From my own experimenting, I tried making vertices from the sphere demo jitter about by assigning random displacements every frame, e.g.: ``` function update() { // update the amplitude based on // the frame value. values = attributes.displacement.value for(var v = 0; v < vertCount; v++) { values[v] = (Math.random() * 30); } renderer.render(scene, camera); // set up the next call requestAnimFrame(update); } ``` However the result is a static misshapen ball. It appears that attributes only take on the first value to which they are assigned. After that, they cannot be updated. However, is this a behavior expected of glsl attributes or is there an additional step I need to take to update attributes? If the latter, is there a workaround available to achieve the desired besides setting vertex positions in javascript?