Three.js补间动画2-形变

439 阅读1分钟

形变一般指的是对几何体顶点位置的修改。 在Three.js中BufferGeometry实例的morphAttributes可以用来存储形变数据, 结合Animation的api实现形变动画。

CPT2303090103-617x660.gif

以一个立方体为例
      const geometry = new THREE.BoxGeometry();
      const material = new THREE.MeshPhongMaterial({ color: 0xffff00 });
      const cube = new THREE.Mesh(geometry, material);
      scene.add(cube);
创建两个形变数据,一个是往x轴拉伸,另一个是往y轴拉伸

morphAttribute存储形变数据,而morphTargetInfluences决定形变的程度

      const pos = geometry.getAttribute("position");
      const expendY = [];
      const expendX = [];
      for (let i = 0; i < pos.count; i++) {
        expendY.push(pos.getX(i));
        expendY.push(pos.getY(i) + (pos.getY(i) > 0 ? 2 : 0));
        expendY.push(pos.getZ(i));

        expendX.push(pos.getX(i) + (pos.getX(i) > 0 ? 2 : 0));
        expendX.push(pos.getY(i));
        expendX.push(pos.getZ(i));
      }
      geometry.morphAttributes.position = [
        new THREE.Float32BufferAttribute(expendY, 3),
        new THREE.Float32BufferAttribute(expendX, 3),
      ];
      cube.morphTargetInfluences = [0, 0];
创建帧动画

有4帧,每帧有两个元素,values总共有8个元素

      const expand = new THREE.KeyframeTrack(
        ".morphTargetInfluences",
        [0, 1, 2, 3],
        [0, 0, 1, 0, 0, 0, 0, 1]
      );
      const clip = new THREE.AnimationClip("expand", 3, [expand]);
      const mixer = new THREE.AnimationMixer();
      const action = mixer.clipAction(clip, cube);
      // action.loop = THREE.LoopPingPong;
      // action.loop = THREE.LoopOnce;
      action.play();
动画渲染
      const clock = new THREE.Clock();
      renderer.setAnimationLoop((t) => {
        mixer.update(clock.getDelta());
        renderer.render(scene, camera);
      });