1、安装依赖

  • npm install three --save --force 或 yarn add three

使用示例

t
<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>