Threejs加载MMD

简介: 这篇文章详细介绍了如何在Three.js中加载和使用MMD(MikuMikuDance)模型,包括模型的导入、动画的播放以及与MMD相关的文件格式和操作流程。

MMD全称MikuMikuDance,是一个简单的做动画的程序,做MMD之前先了解下什么是PMD。

PMD(Polygon Model Data)文件是一种用于描述三维模型的文件格式。PMD 文件通常用于 MikuMikuDance(MMD)软件,它是一款在日本非常流行的三维角色动画制作工具。PMD 文件包含了模型的几何形状、材质、骨骼和动画数据等信息,可以被导入到 MMD 中进行编辑和动画制作。PMD 文件是一种比较常见的三维模型文件格式,在虚拟角色创作和动画制作方面得到广泛应用。

之前我以为其他模型和gltf一样,加载进来可以显示,如果有动画可以播放动画,后来在官网看到mmd发现还是有区别的,因为他做好了统一的骨骼模型,然后动作文件是vmd格式分开的,这就意味着可以加载一个模型后选择不同的动作动画,然后实现不同的动画效果,而只需要切换动画就好了,下面引用官网的例子,结合vue来实现一下:

因为是基于Threejs的,所以还是需要创建threejs的基础场景,包括场景,相机,灯管等:

 initScene(){
      this.scene = new THREE.Scene();
      this.clock = new THREE.Clock();
      const gridHelper = new THREE.PolarGridHelper( 30, 0 );
      this.scene.add(gridHelper)
    },
    initCamera(){
      this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 10000);
      this.camera.position.set(100,100,100);
      this.camera.lookAt(0,0,0);

      this.listener = new THREE.AudioListener();
      this.camera.add( this.listener );
      this.scene.add( this.camera );
    },
    initLight(){
      //添加两个平行光
      const directionalLight1 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight1.position.set(-300,-300,600)
      this.scene.add(directionalLight1);
      const directionalLight2 = new THREE.DirectionalLight(0xffffff, 1.5);
      directionalLight2.position.set(600,200,600)
      this.scene.add(directionalLight2);
    },
initRenderer(){
      this.renderer = new THREE.WebGLRenderer({ antialias: true });
      this.container = document.getElementById("container")
      this.renderer.setSize(this.container.clientWidth, this.container.clientHeight);
      this.renderer.setClearColor('#FFFFFF', 1.0);
      this.container.appendChild(this.renderer.domElement);
    },
    initControl(){
      this.controls = new OrbitControls(this.camera, this.renderer.domElement);//创建控制器
      this.controls.enableDamping = true;
      this.controls.maxPolarAngle = Math.PI / 2.2;      // // 最大角度
      this.controls.target = new THREE.Vector3(0, 0, 0);
      this.camera.position.set(100, 100, 100);
      this.camera.lookAt(0, 0, 0);
    },
    initAnimate() {
      requestAnimationFrame(this.initAnimate);
      this.renderer.render(this.scene, this.camera);
      if ( this.ready ) {
        this.helper.update( this.clock.getDelta() );
      }
    },

有了这个空间后,需要先引入mmd的加载器,用来加载PMD的模型文件。也包括MMD的动画助手插件用来渲染动画,两个插件加载不分先后顺序,第一个是把模型加载进来,第二个是做出动画效果。

import {MMDLoader} from "three/examples/jsm/loaders/MMDLoader";
import {MMDAnimationHelper} from "three/examples/jsm/animation/MMDAnimationHelper";

有了这两个组件后,就可以开始着手加载模型和动画了,首先,我们创建一个MMDAnimationHelper和MMDLoader的实例,然后利用MMDLoader的loadWidthAnimation方法加载模型和动画,loadWidthAnimation包括多个参数:modelUrl : String, vmdUrl : String, onLoad : Function, onProgress : Function, onError : Function,第一个也就是模型地址,第二个是动作文件地址,第三个是加载函数,第四个是加载进度,如果模型大的话可以在这里获取到加载进度,做成进度条,最后一个是加载错误的处理方法,

 this.helper = new MMDAnimationHelper();
      const loader = new MMDLoader();
      let _this = this

      loader.loadWithAnimation( '/static/tuote/tuote.pmx', '/static/tuote/12.vmd', function ( mmd ) {
        _this.scene.add( mmd.mesh );
        _this.helper.add( mmd.mesh, {
          animation: mmd.animation,
          physics: true
        });
      }, null, null );

然后,你的浏览器上就会出现一个会动的小姑娘,

我们可以用官网例子的方式加上PolarGridHelper,做出脚底光环的效果

      const gridHelper = new THREE.PolarGridHelper( 30, 0 );
      this.scene.add(gridHelper)

接着我们可以加入相机动画,制作比较动感的视觉效果,就像动画中也会有镜头拉近,拉远,等各个角度的变换拍摄,加载好相机动画后就可以看到相机也会不断地切换角度拍摄

      loader.loadAnimation( '/static/animal/wavefile_camera.vmd', this.camera, function ( cameraAnimation ) {
        _this.helper.add( _this.camera, {
          animation: cameraAnimation
        } );
      }, null, null );

这还不够,好看的画面得配上音乐,所以,我们再添加进音乐

      new THREE.AudioLoader().load( '/static/animal/wavefile_short.mp3', function ( buffer ) {
        const audio = new THREE.Audio( _this.listener ).setBuffer( buffer );
        const audioParams = { delayTime: 160 * 1 / 30 };
        _this.helper.add( audio, audioParams );
        _this.ready = true;
      }, null, null );

这样才算一个较为完整的动画效果,
WechatIMG130.jpg
MMD动画

这里不支持上传视频,我就上传个图片了,如果想看动态效果可以私我,我发给你视频

下面我们尝试切换一个动作文件,其实只需要改变动作文件的引用就好了


      loader.loadWithAnimation( '/static/animal/miku_v2.pmd', '/static/tuote/12.vmd', function ( mmd ) {
        _this.scene.add( mmd.mesh );
        _this.helper.add( mmd.mesh, {
          animation: mmd.animation,
          physics: true
        });
      }, null, null );

然后再来看下效果
WechatIMG126.jpg
MMD动画2

这里不支持上传视频,我就上传个图片了,如果想看动态效果可以私我,我发给你视频

相关文章
|
JavaScript
Threejs实现PMD模型眨眼说话等功能
这篇文章详细介绍了如何在Three.js中实现PMD模型的眨眼和说话等动态效果,通过控制模型的关键帧来模拟面部表情的变化。
417 0
Threejs实现PMD模型眨眼说话等功能
Threejs实现模拟河流,水面水流,水管水流,海面
Threejs实现模拟河流,水面水流,水管水流,海面
3409 0
Threejs实现模拟河流,水面水流,水管水流,海面
|
算法 程序员
从《阴阳师》到《原神》,抽卡中的程序算法
收集类的抽卡手游,是玩家们喜闻乐见的一类游戏,他们背后又有哪些程序算法?我们一起来探讨
4291 0
从《阴阳师》到《原神》,抽卡中的程序算法
Threejs创建天空和太阳
这篇文章讲解了如何使用Three.js中的Sky组件来创建真实的天空与太阳效果,包括调整天空的颜色、太阳的位置以及实现大气散射等技巧。
519 3
ThreeJs添加拖动辅助线
这篇文章介绍了在Three.js中使用TransformControls组件来添加拖动辅助线,实现对3D模型在不同轴向上进行直观的拖动和平移操作。
469 0
|
JavaScript 前端开发 开发者
ThreeJs控制模型骨骼实现数字人
这篇文章讲解了如何使用Three.js通过控制模型的骨骼来实现数字人的动态表现,包括加载模型、获取骨骼信息以及通过编程控制骨骼动作的具体方法。
1375 1
Threejs播放模型自带动画
这篇文章介绍了在Three.js中如何播放带有预设动作的模型动画,并特别提到了如何设置动画循环模式以实现一次性播放效果。
489 3
Threejs播放模型自带动画
ThreeJs给物体添加贴图
这篇文章详细说明了在Three.js中如何给3D物体添加贴图,并展示了实现局部贴图的技术和方法。
631 1
ThreeJs给物体添加贴图
ThreeJs手动控制动画播放与暂停
这篇文章介绍了如何在Three.js中手动控制动画的播放与暂停,包括设置动画混合器、监听按键事件以调整动画状态和速度的方法。
430 0
ThreeJs手动控制动画播放与暂停
Threejs用官方提供的编辑器做一个简单的模型
这篇文章介绍了如何使用Three.js内置的编辑器来创建和编辑简单的3D模型,并提供了相应的操作指南。
1348 1