美文网首页
Three.js 导入 MMD 模型

Three.js 导入 MMD 模型

作者: 御坂12315 | 来源:发表于2022-12-13 11:21 被阅读0次

项目信息

版本: "three": "^0.147.0"
模型来源:https://www.aplaybox.com
完整项目: https://github.com/yuban12315/hutao

demo 效果

首先需要初始化场景,摄像机,渲染器,光照等,然后我们使用 MMDLoader 加载 MMD 模型。

Loader 部分

import scene from "./scene";
import * as THREE from "three";
import { MMDLoader } from "three/examples/jsm/loaders/MMDLoader.js";
import { MMDAnimationHelper } from "three/examples/jsm/animation/MMDAnimationHelper.js";
import camera from "./camera";

export const helper = new MMDAnimationHelper();

export class Loader {
  loadModels() {
    const loader = new MMDLoader();

    loader.loadWithAnimation(
      "/public/hutao/胡桃.pmx", 
      "/public/move/ayaka-dance.vmd",
      function onLoad(mmd) {
        // called when the resource is loaded
        const { mesh } = mmd;
        helper.add(mmd.mesh, {
          animation: mmd.animation,
        });

        scene.getScene().add(mmd.mesh);
      }
    );

    loader.loadAnimation(
      "./public/move/ayaka-camera.vmd",
      camera.getCamera(),
      function (cameraAnimation) {
        helper.add(camera.getCamera(), {
          animation: cameraAnimation as THREE.AnimationClip,
        });
      }
    );
  }
}

export default new Loader();

在 three.js 中可以使用 MMDLoader 加载适用于 MMD 的文件(.pmx,.vmd 等),如果只要加载一个静态的模型,可以使用 new MMDLoader().load 方法,加载带动作的模型则可以使用 loadWithAnimation 方法。两者都需要在回调函数中将模型的 mesh 添加到场景中。

也可以单独使用 loadAnimation 加载动画,这里用来加载相机的动画。
当相机绑定上动画后,在每次渲染时都会根据动画的内容更新相机的位置,角度等,但此时你仍然可以给相机绑定控制器,通过用户输入来移动相机。

initControls() {
    const controls = new OrbitControls(
      camera.getCamera(),
      renderer.getRenderer().domElement
    );

    // 使用了 OrbitControls,camera 对象的 lookAt 方法失效
    // 这里通过调整  controls.target 控制初始摄像机的位置
    controls.target = new THREE.Vector3(1.6, 14, -4);
    this.controls = controls;
  }

这里的 MMDAnimationHelper 用来处理模型的动画效果,将需要绑定动画的对象和动画传递进去后,还需要在渲染时调用 helper.update 方法更新动画效果:

  constructor() {
    const container = document.getElementById("three");
    if (!container) {
      return;
    }
    this.clock = new THREE.Clock();

    scene.init(container);
    camera.init(container);
    renderer.init(container);
  }

   render() {
    loader.loadModels();
    // this.initControls();
    this.initLight();

    this.callRenderer();
  }

  callRenderer() {
    this.frameId = requestAnimationFrame(() => {
      // this.controls.update();
      const time = this.clock.getDelta();
      helper.update(time);
      renderer.getRenderer().render(scene.getScene(), camera.getCamera());
      this.callRenderer();
    });
  }

加载依赖,动画效果中的物理效果需要使用 ammo.js, 这里可以项目中引入并初始化。

<script src="./public/ammo.js">
    Ammo().then(function (AmmoLib) {
      Ammo = AmmoLib;
      init(); animate();
    })
</script>

相关文章

网友评论

      本文标题:Three.js 导入 MMD 模型

      本文链接:https://www.haomeiwen.com/subject/xfoqqdtx.html