概述
如有不明白的可以加QQ:2354528292;wx: aichitudousien
更多教学视频请访问:https://space.bilibili.com/236087412
详细教学请到上方视频链接访问,总共3个多小时的教学~
Three.js车展系统
搭建开发环境
使用的开发框架是vue-cli3.0,报表使用echarts, webgl使用three.js,开发工具为vscode
搭建完成后的目录为
搭建three场景
- 创建一个class,用来初始化场景,渲染器,相机,灯光,控制器
import * as THREE from 'three'
import {
OrbitControls
} from 'three/examples/jsm/controls/OrbitControls.js';
import {
OBJLoader
} from 'three/examples/jsm/loaders/OBJLoader';
import {
MTLLoader
} from 'three/examples/jsm/loaders/MTLLoader';
export default class ZThree {
constructor(id) {
this.id = id;
this.el = document.getElementById(id);
}
// 初始化场景
initThree() {
let _this = this;
let width = this.el.offsetWidth;
let height = this.el.offsetHeight;
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(45, width / height, 1, 3000)
this.renderer = new THREE.WebGLRenderer({
antialias: true,
alpha: true
})
this.renderer.setPixelRatio(window.devicePixelRatio)
this.renderer.setSize(width, height)
this.el.append(this.renderer.domElement)
this.renderer.setClearColor('#000')
window.addEventListener('resize', function () {
_this.camera.aspect = _this.el.offsetWidth / _this.el.offsetWidth;
_this.camera.updateProjectionMatrix();
_this.renderer.setSize(_this.el.offsetWidth, _this.el.offsetWidth);
}, false)
}
// 初始化helper
initHelper() {
this.scene.add(new THREE.AxesHelper(100))
}
// 初始化控制器
initOrbitControls() {
let controls = new OrbitControls(this.camera, this.renderer.domElement)
controls.enableDamping = true
controls.enableZoom = true
controls.autoRotate = false
controls.autoRotateSpeed = 0.3
controls.enablePan = true
this.controls = controls
}
initLight() {
let directionalLight = new THREE.DirectionalLight('#fff')
directionalLight.position.set(30, 30, 30).normalize()
this.scene.add(directionalLight)
let ambientLight = new THREE.AmbientLight('#fff', 0.3)
this.scene.add(ambientLight)
return {
directionalLight,
ambientLight
}
}
}
- 在vue文件中调用此类初始化three
<template>
<div id="box" class="container"></div>
</template>
<script>
import ZThree from "@/three/ZThree";
import * as THREE from "three";
let app, camera, scene, renderer, controls, clock, cityModel;
export default {
name: "Home",
components: {},
methods: {
async initZThree() {
app = new ZThree("box");
app.initThree();
app.initHelper();
app.initOrbitControls();
app.initLight();
window.app = app;
camera = app.camera;
scene = app.scene;
renderer = app.renderer;
controls = app.controls;
clock = new THREE.Clock();
camera.position.set(30, 30, 30);
},
},
mounted() {
this.initZThree();
},
};
</script>
<style lang='less' scoped>
.container {
width: 100%;
height: 100%;
overflow: hidden;
background-color: #000;
}
</style>
此时我们可以看到的场景是,如果能够看到坐标轴辅助线,代表我们的场景已经加载成功
此时我们已经成功创建了three的场景,接下来我们开始加载模型,天空盒等更加好玩的东西~
加载模型
- 在ZThree类中加入loaderObjModel方法用来加载模型
// 加载obj模型
loaderObjModel(path, objName, mtlName) {
return new Promise(resolve => {
new MTLLoader()
.setPath(path)
.load(mtlName + '.mtl', function (materials) {
console.log(materials)
materials.preload();
// 加载obj
new OBJLoader()
.setPath(path)
.setMaterials(materials)
.load(objName + '.obj', function (object) {
resolve(object)
});
});
})
}
- 在vue文件中调用此方法
模型是我随便在网上找的,各位可以随意在网上找一个obj模型来测试即可
cityModel = await app.loaderObjModel(
"model/city/",
"CityIslands",
"City_Islands"
);
scene.add(cityModel);
此时有些小伙伴可能会比较奇怪的是为什么初始化进来时看不到模型或是只能看到模型的一小部分,那是你的相机设置的位置不对,教给大家一个小技巧,我们把app对象给挂载到window对象上,然后我们在调整控制器到视角最好的位置,此时打开控制台,输入app.camera.position和app.controls.target
此时我们就可以看到对应的参数,然后我们在设置一下就ok了
camera.position.set(18, 364, 397);
controls.target = new THREE.Vector3(2, 44, -32);