从着色器的three.js教程中,我们了解到我们可以更新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); }
没有提到的是同样的行为是否扩展到属性.从我自己的实验中,我尝试通过每帧分配随机位移来从球体演示抖动中制作顶点,例如:
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); }
然而,结果是一个静态畸形球.看起来属性仅占用它们所分配的第一个值.之后,他们无法更新.但是,这是glsl属性的预期行为还是我需要采取额外的步骤来更新属性?如果是后者,除了在javascript中设置顶点位置之外,还有可用的解决方法吗?
事实证明,可以更新制服等属性.在我的情况下,我错过了一个重要的代码行:
attributes.displacement.needsUpdate = true;
该教程中省略了该行,添加后我得到了我希望的确切行为.