Exploring the three.js tutorial on shaders, we discover a technique for updating 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);
}
The tutorial does not address whether the same principle applies to attributes. In my own experimentation, I attempted to introduce jitter in the vertices of a sphere demo by assigning random displacements each frame:
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);
}
Unfortunately, this resulted in a static misshapen sphere. It seems that attributes retain only their initial assigned value and cannot be updated subsequently. Is this behavior typical of glsl attributes, or should there be an additional step required for updating attributes? If so, are there any workarounds available aside from manipulating vertex positions directly in javascript?