threejs的vue3尝试和gltf文件3d模型引入

1,469 阅读3分钟

three.js在vue3中的使用,gltf外部3d文件的引入展示,3d图像的拖动缩放

vue版本3.2.45

安装three

npm install three

引入three.js核心库的方式(在组件中或需要的页面)

 // 方式 1: 导入整个 three.js核心库
 import * as THREE from 'three';
 ​
 const scene = new THREE.Scene();
 ​
 ​
 // 方式 2: 仅导入你所需要的部分
 import { Scene } from 'three';
 ​
 const scene = new Scene();

想让3D场景展示出来,我们需要3个对象

1.场景

 const scene = new THREE.Scene()

2.相机

 
 const camera = new TRHEE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
 camera.position.set(50, 50, 100);//设置相机位置
  • PerspectiveCamera里面的4个参数:

    • 第一个是视野角度,是你能在显示器上看到的场景的范围
    • 第二个是长宽比,不合适的长宽比图像会被压缩或者拉伸
    • 第三个是近截面,如下图
    • 第四个是远截面,如下图

3.渲染器

 const renderer = new THREE.WebGLRenderer();
 renderer.setSize( window.innerWidth, window.innerHeight );
 //renderer.setSize(window.innerWidth - 234, window.innerHeight - 155);
  • WebGLRender可以传入一个对象参数进行设置
  • setSize设置宽高,如果在管理后台的layout-main窗口可以设置成注释的样子,数值调整下

这三个有了之后我们开始vue-template代码一行就行

 <div ref=threejsRef />

然后我们把上面的结合起来封装到一个函数中,然后再onMounted中调用

 
 const threejsRef = ref()
 const initThree = ()=>{
     const scene = new THREE.Scene()
     
     const camera = new THREE.PerspectiveCamera(75,window.innerWidth/window.innerHeight,0.1,1000)
     camera.position.set(60, 30, 120);//设置相机位置
     
     const renderer = new THREE.WebGLRenderer();
     renderer.setSize( window.innerWidth, window.innerHeight );
     
     
     //挂载dom
     threejsRef.value.appendChild(renderer.domElement)
     renderer.render(scene, camera);
 }
 onMounted(()=>{
     initThree()
 })

这样一个三维场景就搭建好了,但是是空的黑乎乎的,下面我们加一些东西进去(都写在刚刚的initThree函数中或者拆分出去)

1.首先我们加一个立方体进去

 
  //创建立方体
   const boxgeometry = new THREE.BoxGeometry(20, 20, 20);
   const boxMaterial = new THREE.MeshBasicMaterial({
     color: 0x77777ff,
     wireframe: true
   });
   const box = new THREE.Mesh(boxgeometry, boxMaterial);
   scene.add(box);

2.我们得到一个立方体,但是他是固定的,下面我们让他动起来

 import Stats from "three/examples/jsm/libs/stats.module"; //用来开启帧数监听
 // 开启监听帧数
 const stats = new Stats();
 //创建动画函数
 const animate = () => {
     stats.update(); //每一帧都更新
     requestAnimationFrame(animate);
 ​
     box.rotation.x += 0.01;
     box.rotation.y += 0.01;
     renderer.render(scene, camera);
     //让渲染区域和窗口尺寸响应式同步
     window.onresize = function () {
       camera.aspect = dom.value.clientWidth / dom.value.clientHeight; //相机重新计算宽高比
       camera.updateProjectionMatrix(); //刷新相机,和update()类似
       renderer.setSize(dom.value.clientWidth, dom.value.clientHeight); // 改动渲染器尺寸
     };
   };

这样我们的立方体就转起来了,但是这种立方体还是太丑了,我们需要从外面引入一些3d模型,用blender等制作的,然后导出为gltf文件。那么如何引入gltf文件呢

首先我们引入three.js自带的加载器

 import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader.js";

还是在我们刚才的函数的我们把立方体相关的代码和动画函数中两行box相关代码注释掉,得到了我们黑乎乎的画面,然后在里面写

   const loader = new GLTFLoader();
   loader.load(
     "productionline.gltf",
     gltf => {
       console.log(gltf);
       scene.add(gltf.scene);
       camera.lookAt(gltf.scene.position);
       gltf.animations; // Array<THREE.AnimationClip>
       gltf.scene; // THREE.Group
       gltf.scenes; // Array<THREE.Group>
       gltf.cameras; // Array<THREE.Camera>
       gltf.asset; // Object
     },
     function (xhr) {
       console.log((xhr.loaded / xhr.total) * 100 + "% loaded");
     },
     // called when loading has errors
     function (error) {
       console.log("An error happened");
     }
   );

这里有个坑的地方就是文件路径问题,我是放在public下面的,注意下有没有./

写完这个代码后我们加载好了,但是还是灰色的看不见,我们需要给他一个光源(图像大小注意调整camera的第一个参数和camera的位置)

 // 创建光源
   const light = new THREE.PointLight(0xffffff, 1, 100);
   light.position.set(30, 30, 0);
   scene.add(light);

好了我们的图像亮了,但是他是固定的不能拖动的,我们给他添加下轨道

 // // 导入轨道模型控制器
 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls"; 
 //添加轨道-可以鼠标随意拖拽
   const controls = new OrbitControls(camera, renderer.domElement);
   controls.target.set(0, 0, 0); //设定中心点
   controls.update(0); //重新设置轨道,相当于刷新

好了到此我们就可以拖动和滚轮缩放了,我们成功的加载了gltf的3d图像。

最终的效果:

企业微信截图_16856040876837.png 需要完整代码的可私信