Javascript 更新three.js中的ShaderMaterial属性

Javascript 更新three.js中的ShaderMaterial属性,javascript,three.js,glsl,webgl,vertex-shader,Javascript,Three.js,Glsl,Webgl,Vertex Shader,从中,我们了解到可以更新着色器材质的统一值: 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

从中,我们了解到可以更新着色器材质的统一值:

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);
  }
函数更新(){
//根据以下内容更新振幅:
//帧值。
值=attributes.displacement.value
对于(var v=0;v

然而,结果是一个静态的畸形球。属性似乎只接受分配给它们的第一个值。之后,它们将无法更新。然而,这是glsl属性的预期行为还是我需要采取额外的步骤来更新属性?如果是后者,除了在javascript中设置顶点位置外,是否还有其他解决方法可以实现所需的目标?

结果表明,可以更新制服等属性。在我的例子中,我遗漏了一行非常重要的代码:

attributes.displacement.needsUpdate = true;
教程中省略了这一行,添加它后,我得到了我所希望的确切行为