three.js官网 threejs.org/
1 在项目中使用 npm方式
npm install --save three
2 创建场景--在场景中添加相机,轨道控制器,灯光,渲染器.
<template>
<div id="container"></div>
</template>
<script>
import * as THREE from 'three';
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
let scene, camera, renderer, controls, mesh,css2Renderer;
export default {
mounted() {
this.init();
},
methods:{
//可以根据需要对init方法进行拆分
init(){
scene = new THREE.Scene();
const element = document.getElementById("container");
const width = element.clientWidth; // 窗口宽度
const height = element.clientHeight; // 窗口高度
const k = width / height; // 窗口宽高比
camera = new THREE.PerspectiveCamera(35, k, 0.1, 10000);
camera.position.set(20, 20, 500); // 设置相机位置
camera.lookAt(new THREE.Vector3(10, 40, 0)); // 设置相机方向
scene.add(camera);
// 环境光
const ambientLight = new THREE.AmbientLight(0x404040, 0.1); // 环境光
scene.add(ambientLight); // 将环境光添加到场景
const spotLight = new THREE.SpotLight(0xffffff); // 创建聚光灯
spotLight.position.set(50, 50, 50);
spotLight.castShadow = true;
scene.add(spotLight);
controls = new OrbitControls(camera, renderer.domElement);
// 使动画循环使用时阻尼或自转 意思是否有惯性
controls.enableDamping = true;
//动态阻尼系数 就是鼠标拖拽旋转灵敏度
//controls.dampingFactor = 0.25;
//是否可以缩放
// controls.enableZoom = false;
//是否自动旋转
controls.autoRotate = false;
//设置相机距离原点的最远距离
controls.minDistance = 200;
//设置相机距离原点的最远距离
controls.maxDistance = 10000;
//是否开启右键拖拽
controls.enablePan = true;
const element = document.getElementById("container");
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(element.clientWidth, element.clientHeight); // 设置渲染区域尺寸
renderer.domElement.id = "canvas"
renderer.shadowMap.enabled = true; // 显示阴影
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
renderer.setClearColor("transparent", 0); // 设置背景颜色
element.appendChild(renderer.domElement);
renderer.domElement.addEventListener("click",this.handleClick)
},
render() {
controls.update()
renderer.render(scene, camera);
requestAnimationFrame(this.render);
},
}
}
</script>
3 在场景中添加模型--场景中添加fbx和glb格式的模型
<script>
import { GLTFLoader, GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js'
import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader.js'
export default{
methods:{
loadModelByUrL(url) {
// 创建 FBXLoader 实例
let fileType = this.getFileType(url) //获取文件类型
let loader
if (fileType) {
if (fileType.toUpperCase() === 'FBX') {
loader = new FBXLoader()
loader.load(url, (object) => this.handleFBXModel(object as THREE.Group))
} else if (fileType.toUpperCase() === 'GLB') {
loader = new GLTFLoader()
loader.load(url, (data) => this.handleGLTFModel(data))
}
}
},
getFileType(url) {
const filename = url.split('/').pop() // 获取 URL 最后的部分,即文件名
const extension = filename && filename.slice(-3) // 获取文件名最后三个字符作为扩展名
return extension
},
handleFBXModel(model) {//添加fbx模型并为模型设置颜色
let childModels = []
model.traverse((child) => {
// 可以选择存储子对象的名称,或者整个THREE.Object3D对象
if (child instanceof THREE.Mesh) {
const materials = child.material
if (Array.isArray(materials)) {
// 处理 material 数组的情况
materials.forEach((material) => {
if ('color' in material) {
// 首先也确保material有color属性
;(material as THREE.Material & { color: THREE.Color }).color.set(0xffffff)
material.needsUpdate = true
childModels.push(material)
}
})
} else {
// 处理单个 material 的情况
if ('color' in materials) {
;(materials as THREE.Material & { color: THREE.Color }).color.set(0xffffff)
materials.needsUpdate = true
}
}
}
})
scene.add(model)
this.render()
},
handleGLTFModel(gltf) {
let model = gltf.scene
scene.add(model)
this.render()
}
}
}
</script>