Three.js 模型加载及加载简单动画

时间过的好快啊~再一次感叹,忙忙碌碌一年又过去了,新年第一帖,新的一年也要加油呀!

简单介绍下Three.js吧,Three.js是基于原生WebGL封装运行的三维引擎,在所有WebGL引擎中,Three.js是国内文资料最多、使用最广泛的三维引擎。因为使用简单,入门比较容易。

Three.js的具体介绍和使用有很多教程,可以根据自己需要搜索。它重要的三个属性:场景(scene),相机(camera),渲染器(renderer),组合构成一个三维画面。

创建一个div容器,用于加载模型

 <div v-loading="loadModel"
             element-loading-text="模型渲染中"
             element-loading-spinner="el-icon-loading"
             element-loading-background="rgba(0, 0, 0, 0)"
             ref="threeBox"
             class="three-box" />

初始化数据

 loadModel: true, // 模型加载状态
      scene: null, // 3D模型场景
      camera: null, // 摄像机
      renderer: null, // 渲染器
      mixer: null, // 动画帧
      clock: null, // 锁
      glbLoader: null,
      dracoLoader: null,

 渲染模型

// 渲染模型
    init() {
      // eslint-disable-next-line @typescript-eslint/no-this-alias
      const self = this;
      self.scene = new THREE.Scene();
      self.camera = new THREE.PerspectiveCamera(45, self.$refs.threeBox.clientWidth / self.$refs.threeBox.clientHeight, 0.1, 10000);
      self.renderer = new THREE.WebGLRenderer();
      self.renderer.setClearColor('0xffffff', 0);
      self.renderer.setSize(self.$refs.threeBox.clientWidth * 1.07, self.$refs.threeBox.clientHeight);
      self.$refs.threeBox.appendChild(this.renderer.domElement);
      // self.scene.add(new THREE.AxesHelper(1000));
      self.controls = new OrbitControls(self.camera, self.renderer.domElement);
      self.controls.target.set(0, 0, 0);
      self.controls.update();
      const boxHelper = new THREE.BoxHelper();
      // 加载glb模型
      const fbxLoader = new FBXLoader();
      const actives = [];
      self.glbLoader = new GLTFLoader();
      self.dracoLoader = new DRACOLoader();
      self.dracoLoader.setDecoderPath('draco/');
      self.dracoLoader.setDecoderConfig({ type: 'js' });
      self.dracoLoader.preload();
      self.glbLoader.setDRACOLoader(self.dracoLoader);
      self.glbLoader.load(self.modelPath, (obj) => {
        const object = obj.scene;
        boxHelper.setFromObject(object);
        const { center } = boxHelper.geometry.boundingSphere;
        const { radius } = boxHelper.geometry.boundingSphere;
        const cameraPos = new THREE.Vector3(center.x + object.position.x, center.y + object.position.y, radius * 2.2 + center.z + object.position.z);
        const lookPos = new THREE.Vector3(center.x + object.position.x, center.y + object.position.y, center.z - object.position.z);
        object.rotation.y = (-90 * Math.PI) / 180;
        object.rotation.z = (-45 * Math.PI) / 180;
        self.camera.position.copy(cameraPos);
        self.controls.target = lookPos;
        self.camera.lookAt(lookPos);
        self.scene.add(object);
        self.loadModel = false;
        // 加载动画帧
        self.mixer = new THREE.AnimationMixer(object);
        obj.animations.forEach((item) => {
          actives.push(self.mixer.clipAction(item));
        });
        actives[0].play();
      });
      // 环境光
      const ambient = new THREE.AmbientLight(0xffffff);
      this.scene.add(ambient);
      // 点光源
      const point1 = new THREE.PointLight(0xD3D3D3);
      point1.position.set(200, 400, 300);
      self.scene.add(point1);
      const point2 = new THREE.PointLight(0xD3D3D3);
      point2.position.set(-200, -400, -300);
      self.scene.add(point2);
      self.camera.position.set(100, 200, 300);
      self.camera.lookAt(0, 0, 0);
    },

其中modelPath是放在public下面的模型路径,这里以glb模型为例,可以改为自己对应的glb模型地址。该模型中里面包含了动画,在加载完模型的时候,加载动画帧(mixer

modelPath: '/model/model-processed.glb', // glb模型路径

加载动画

 // 加载动画
    animate() {
      if (this.mixer) {
        this.mixer.update(this.clock.getDelta());
      }
      requestAnimationFrame(this.animate);
      this.renderer.clear();
      this.renderer.render(this.scene, this.camera);
      this.renderer.clearDepth();
    },

初始化调用

mounted() {
    this.$nextTick(() => {
      this.clock = new THREE.Clock();
      this.init();
      this.animate();
    });
  },

最终效果图

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值