介绍: 主要总结threeJs在vue中的使用
安装引入
npm install three
import * as THREE from 'three';
- 最好确定版本号,以免three更新造成版本不兼容问题
- 使用轨道控制器、加载器等时,还需要另行引入
数据初始化
- 全局变量准备
scene: null,
camera: null,
renderer: null,
objects: null,
- 容器准备
// 数据初始化
initData() {
this.container = this.$refs.three; //容器
},
创建场景
Scene – three.js docs (threejs.org)
// 创建场景
createScene() {
this.scene = new THREE.Scene();
this.scene.environment = 环境贴图 ; //若该值不为null,则该纹理贴图将会被设为场景中所有物理材质的环境贴图。
},
创建相机
- 透视相机 PerspectiveCamera:进大远小,模拟人眼
- 正交相机:视锥体就是一个立方体,无近大远小,永远渲染2d场景或者ui元素
设置合适的相机参数
// 创建相机
createCamera() {
this.camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight, // 一般设置为canvas画布宽高比
0.9,
100
);
// 相机位置
this.camera.position.set(0, 2, 10);
// 观察目标点的坐标
this.camera.lookAt(this.scene.position);
this.scene.add(this.camera);
},
创建轨道控制器——控制相机
Orbit controls(轨道控制器)可以使得相机围绕目标进行轨道运动。
轨道控制器会影响lookAt的设置,注意手动修改
control
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
// 创建控制器
createOrbitControls() {
this.controls = new OrbitControls(this.camera, this.renderer.domElement);
this.controls.enableDamping = true; // 启用阻尼
this.controls.minPolarAngle = 0.5; // 最小绕y轴角度
this.controls.maxPolarAngle = 1.35; // 最大绕y轴角度
this.controls.zoomSpeed = 0.3; // 放慢缩放速度
},
// 加载
render() {
this.renderer.render(this.scene, this.camera);
this.controls && this.controls.update(); //使用控制器后,必须在加载的时候update
requestAnimationFrame(this.render);
},
创建灯光
- 环境光ambient:环境光会均匀的照亮场景中所有物体,环境光不能用来投射阴影,因为它没有方向。
- 平行光directionalLight :类似于太阳光
- 点光源pointLight:类似于灯泡
- 聚光灯spotlight:类似于手电筒
// 添加燈光
createLight() {
let light1 = new THREE.DirectionalLight(0xffffff, 1); // 创建一个方向光,参数为光的颜色和强度
light1.position.set(0, 0, 10);
this.scene.add(light1);
},
创建渲染器
// 创建渲染器
createRenderer() {
this.renderer = new THREE.WebGL1Renderer();
this.renderer.setSize(
this.container.clientWidth,
this.container.clientHeight
);
this.renderer.antialisa = true; // 抗锯齿
// this.renderer.setClearColor("pink"); // 设置画面颜色
this.container.appendChild(this.renderer.domElement);
},
创建网格地面
// 创建网格地面
createGridHelper() {
const gridHelper = new THREE.GridHelper(10, 10); // size divisions
this.scene.add(gridHelper);
// gridHelper.material.transparent = true;
// gridHelper.material.opacity = 0.5;
},
创建坐标轴辅助器
// 创建坐标轴辅助器
createAxesHelper() {
const axesHelper = new THREE.AxesHelper(5);
this.scene.add(axesHelper);
},
载入模型
载入3D模型 – three.js docs (threejs.org) GLTFLoader – three.js docs (threejs.org)
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';
const loader = new GLTFLoader();
loader.load(
"path/to/model.glb",
(gltf) => {
console.log("模型加载完毕...")
this.scene.add(gltf.scene);
// 遍历模型,拿到目标子模型
glft.scene.traverse((child) => {
if (child.name === "door_right") {
this.rightDoor = child;
}
})
},
);
- 加载地址写打包后的相对地址,否则可能加载不出来
- blender 导出的部分纹理,threejs可能无法加载出,如:颜色渐变等
- 载入模型后,记得根据模型调节相机参数
自定义mesh
createMesh () {
const box = new THREE.BoxGeometry(1, 1, 1);
// 材质:MeshStandardMaterial标准网格材质,是基于物理渲染的,能够基于物理模型处理灯光和阴影,更接近物理世界的真实场景。
const material = new THREE.MeshStandardMaterial({ color: 0xffff00 })
// 物体
const cube = new THREE.Mesh(box, material);
cube.castShadow = true; // 设置物体的投射阴影
this.scene.add(cube)
},