Vue快速应用配置Three.js
- 前言
- 一、引用Three.js
- 二、定义全局数据
- 三、代码部分--加载一个简单的正方体
- 四、加载外部模型
前言
1 2 3 | 当前项目需要搭建一个农场的3D模型,就想到了使用Three.js 但是,在网络中VUE使用Three.js的文章是在是少之又少,特此记录一下 如需转载,请标明来源 |
一、引用Three.js
npm 引用:
页面import
1 2 3 4 | import Stats from 'stats-js' // 帧速率显示 import * as Three from 'three' // 引用Three.js import OrbitControls from 'three-orbitcontrols' //鼠标 import {<!-- --> OBJLoader, MTLLoader} from 'three-obj-mtl-loader' |
二、定义全局数据
1 2 3 4 5 6 7 8 9 10 11 12 13 | data() {<!-- --> return {<!-- --> show: false, stats: null, // 用于显示帧速率 camera: null, // 相机 scene: null, // scene对象 renderer: null, // 加载器 labelRenderer: null, //CSS2D加载器 mouse: null, // 鼠标对象 controls: null, // 鼠标旋转 publicPath: process.env.BASE_URL, // public地址 } } |
1 | 此处的publicPath是为了更方便的引用外部OBJ模型和MTL文件 |
项目中往往不会全部由前端进行模型的构建,此时就需要引入外部的模型,比较常用的就是OBJ模型,引用时需要注意所有需要加载的文件都需要放在public目录下
三、代码部分–加载一个简单的正方体
1 | 废话不多说,直接上代码 |
1 2 | <div id="Stats-output"/> // 用于加载帧速率显示器--没有需求的话可以不写 <div id="container"/> // 加载3D模型主题 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | init() {<!-- --> // state 加载帧速率显示器 this.stats = new Stats() this.stats.setMode(0) const state = document.getElementById('Stats-output') state.appendChild(this.stats.domElement) // 获取到实例 const container = document.getElementById('container') // 获取相机 此处使用的是透视相机 this.camera = new Three.PerspectiveCamera(80, container.clientWidth/container.clientHeight, 1, 10000) // 此处用于设置相机位置 this.camera.position.set(300, 200, 300) this.scene = new Three.Scene() // 加载辅助坐标系 实际应用的时候需要注释此代码 const axisHelper = new Three.AxisHelper(250) this.scene.add(axisHelper) // 聚光源 const spotLight = new Three.SpotLight(0xac6c25); // 设置聚光光源位置 spotLight.position.set(-500, 200, 500); // 聚光灯光源指向网格模型 // spotLight.target = this.mesh; // 设置聚光光源发散角度 spotLight.angle = Math.PI / 6 spotLight.penumbra = 1 spotLight.name = '聚光灯' this.scene.add(spotLight);//光对象添加到scene场景中 // 环境光 const ambient = new Three.AmbientLight(0xFFFFFF) ambient.name = '环境光' this.scene.add(ambient) // 加载器 this.renderer = new Three.WebGLRenderer({<!-- --> antialias: true }) this.renderer.setSize(container.clientWidth, container.clientHeight) container.appendChild(this.renderer.domElement) this.renderer.setClearColor(0xffffff, 0.9) }, // 鼠标控制器 this.getOrbitControls() |
鼠标控制器—通过鼠标控制模型的旋转
1 2 3 4 5 6 7 8 9 10 | // 鼠标旋转 getOrbitControls() {<!-- --> this.controls = new OrbitControls(this.camera, this.renderer.domElement) // 设置相机距离原点的最近距离 this.controls.minDistance = 300 // 设置相机距离原点的最远距离 this.controls.maxDistance = 500 // 是否开启右键拖拽 // this.controls.enablePan = true }, |
渲染动画
1 2 3 4 5 6 7 | animate() {<!-- --> requestAnimationFrame(this.animate) // 更新帧数显示 this.stats.update() // 更新加载器 this.renderer.render(this.scene, this.camera) }, |
所有的函数准备完毕后在mounted()函数中开始引用
1 2 3 4 | mounted() {<!-- --> this.init() // 初始化函数 this.animate() // 渲染 }, |
此时一个场景就加载完成了
但是当前还没有创建任何的模型
写一个函数getCube()用于创建一个常见的正方体
1 2 3 4 5 6 7 8 9 10 11 | getCube() {<!-- --> // 获取材质 const material = new Three.MeshBasicMaterial({<!-- --> color: 0x5C3A21 }) const cube = new Three.BoxGeometry(100, 100, 100) const cubeMesh = new Three.Mesh(cube, material) // 控制位置 cubeMesh.position.set(0, 0, 0) // 加载 this.scene.add(cubeMesh) } |
写好后,在任何地方调用都可以 建议放在init()函数的末尾
这样一个简单模型就加载出来了
四、加载外部模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // 加载OBJ和MTL文件 getWall() {<!-- --> const OBJLoader = new Three.OBJLoader()// obj加载器 const MTLLoader = new Three.MTLLoader()// 材质文件加载器 MTLLoader.load(`${<!-- -->this.publicPath}frame/frame.mtl`, mtl => {<!-- --> // obj的模型会和MaterialCreator包含的材质对应起来 OBJLoader.setMaterials(mtl) OBJLoader.load(`${<!-- -->this.publicPath}frame/frame.obj`, obj => {<!-- --> console.log(obj) obj.scale.set(1, 1, 1) // 放大obj组对象 obj.position.set(0, 0, 0) //调整位置 obj.name = '墙' this.scene.add(obj)// 返回的组对象插入场景中 }) }) }, |
同理,写好的函数可以在任何地方使用 建议放在init()函数的末尾
需要注意的是,在加载外部模型的时候,如果MTL文件中使用了贴图,则需要对该文件进行相应的修改