1、安装依赖
- npm install three --save --force 或 yarn add three
使用示例
<template> | |
// 需要添加 :destory-on-close="true" 否则关闭弹框不会销毁数据重复创建多个模型 | |
<el-dialog :destory-on-close="true" v-model="dialogVisible" title="预览模型" width="600" :before-close="handleClose"> | |
<div id="GltfModelContainer" class="w500 h400"> </div> | |
<template #footer> | |
<div class="dialog-footer"> | |
<el-button type="primary" @click="dialogVisible = false"> 关闭 </el-button> | |
</div> | |
</template> | |
</el-dialog> | |
</template> | |
<script setup lang="ts"> | |
<!--添加依赖--> | |
import * as THREE from 'three' | |
import { OrbitControls } from three/examples/jsm/controls/OrbitControls' | |
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' | |
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader' | |
import Stats from 'three/examples/jsm/libs/stats.module' | |
let mesh: any | |
let camera: any | |
let scene: any | |
let renderer: any | |
let controls: any | |
let stats: any | |
<!--弹窗调用方法 elementUI组件--> | |
const dialogVisible = ref(false) | |
/** 查看模型 */ | |
const showModel = async () => { | |
dialogVisible.value = true | |
setTimeout(() => { | |
// 初始化场景、相机和渲染器 | |
createScene() // 创建场景 | |
loadGLTF() // 加载 GLTF 模型 | |
createLight() // 创建光源 | |
createCamera() // 创建相机 | |
createRender() // 创建渲染器 | |
createControls() // 创建控件对象 | |
render() // 渲染 | |
}, 300) | |
} | |
// 创建场景 | |
const createScene = () => { | |
scene = new THREE.Scene() | |
} | |
// 创建控件对象 | |
const createControls = () => { | |
controls = new OrbitControls(camera, renderer.domElement) | |
} | |
// 加载 GLTF 模型 | |
const loadGLTF = () => { | |
const dracoLoader = new DRACOLoader() | |
const loader = new GLTFLoader() | |
dracoLoader.setDecoderPath('/draco/') | |
loader.setDRACOLoader(dracoLoader) | |
// ondelUrl || | |
loader.load( | |
`/model/1800_lowpoly_4gltf.glb`,// 模型路径 | |
(gltf: any) => { | |
scene.add(gltf.scene) | |
// gltf.animations; // Array<THREE.AnimationClip> | |
// gltf.scene; // THREE.Group | |
// gltf.scenes; // Array<THREE.Group> | |
// gltf.cameras; // Array<THREE.Camera> | |
// gltf.asset; // Objects | |
}, | |
undefined, // 进度回调省略 | |
(error) => { | |
console.error('An error happened:', error) | |
} | |
) | |
} | |
// 创建光源 | |
const createLight = () => { | |
// 环境光 | |
const ambientLight = new THREE.AmbientLight(0xffffff, 1) // 创建环境光 | |
scene.add(ambientLight) // 将环境光添加到场景 | |
const spotLight = new THREE.SpotLight(0xffffff) // 创建聚光灯 | |
spotLight.position.set(150, 150, 150) | |
spotLight.castShadow = true | |
scene.add(spotLight) | |
} | |
// 创建相机 | |
const createCamera = () => { | |
const element = document.getElementById('GltfModelContainer') | |
if (element) { | |
const width = element.clientWidth // 窗口宽度 | |
const height = element.clientHeight // 窗口高度 | |
const k = width / height // 窗口宽高比 | |
// PerspectiveCamera( fov, aspect, near, far ) | |
camera = new THREE.PerspectiveCamera(35, k, 0.1, 1000) | |
camera.position.set(20, 20, 20) // 设置相机位置 | |
camera.lookAt(new THREE.Vector3(10, 40, 0)) // 设置相机方向 | |
scene.add(camera) | |
} | |
} | |
// 创建渲染器 | |
const createRender = () => { | |
const element = document.getElementById('GltfModelContainer') | |
console.log(element, 'element') | |
stats = new Stats() | |
if (element) { | |
element.appendChild(stats.dom) | |
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true }) | |
renderer.setSize(element.clientWidth, element.clientHeight) // 设置渲染区域尺寸 | |
renderer.shadowMap.enabled = true // 显示阴影 | |
renderer.shadowMap.type = THREE.PCFSoftShadowMap | |
renderer.setClearColor(0xffffff, 1) // 设置背景颜色 | |
element.appendChild(renderer.domElement) | |
} | |
} | |
</script> |