Three.jsで BlendShape を動かすコード

Three.js では BlendShape = MorphTarget(モーフターゲット) と呼ばれ、
mesh.morphTargetInfluences を操作することで口形状・表情を動かせる

import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';

let scene, camera, renderer;
let model;

function init() {
  // シーン・カメラ・レンダラー
  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 1.5, 3);

  renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  // ライト
  const light = new THREE.DirectionalLight(0xffffff, 1);
  light.position.set(1, 1, 1);
  scene.add(light);

  // GLTF 読み込み
  const loader = new GLTFLoader();
  loader.load('model.glb', (gltf) => {
    model = gltf.scene;
    scene.add(model);

    // 読み込み後にブレンドシェイプを確認
    model.traverse((obj) => {
      if (obj.isMesh && obj.morphTargetInfluences) {
        console.log("MorphTargets:", obj.morphTargetDictionary); 
      }
    });
  });

  animate();
}

function animate() {
  requestAnimationFrame(animate);

  // BlendShape(MorphTarget)を動かす例
  if (model) {
    model.traverse((obj) => {
      if (obj.isMesh && obj.morphTargetInfluences) {

        // 例:口「あ」を 0〜1 でアニメーション
        const t = (Math.sin(Date.now() * 0.002) + 1) / 2;

        // "A" という名前のモーフがある場合を想定
        const index = obj.morphTargetDictionary["A"];
        if (index !== undefined) {
          obj.morphTargetInfluences[index] = t;  // 0〜1で動かす
        }
      }
    });
  }

  renderer.render(scene, camera);
}

init();