网址(加载三维模型gltf):1. 建模软件绘制3D场景(Blender) | Three.js中文网
- 引入
<template> <div id="webgl"></div> </template> <script lang="ts" setup> import { onMounted, onUnmounted } from "vue"; import * as THREE from "three"; import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";//加载器 import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";//鼠标控制器 import { RoomEnvironment } from "three/examples/jsm/environments/RoomEnvironment";//材质 </script>
- 渲染
let animateId: any = null; onMounted(() => { // 创建场景 const scene = new THREE.Scene(); // const url = "/preview.glb"; //本地,public下路径文件地址 const url = `/api/preview/model/${directoryId}/${id}`;//获取glb文件接口地址 scene.background = new THREE.Color(0xfffffff);//场景背景色 // 创建相机 const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 100); camera.position.set(2, 2, 2); camera.lookAt(scene.position); // 创建默认光源 // const directionalLight = new THREE.DirectionalLight(0xbbbbbb, 1); // 平行光,参数1为强度 // directionalLight.position.set(1, 1, 1); // 光源位置 // scene.add(directionalLight); // 将光源添加到场景 // 添加环境光 // const ambientLight = new THREE.AmbientLight(0xffffff, 0.9); // scene.add(ambientLight); // 创建渲染器 const renderer = new THREE.WebGLRenderer(); renderer.setSize(700, 420); document.body.appendChild(renderer.domElement); // 控制器 let control = new OrbitControls(camera, renderer.domElement); control.target.set(0, 0, 0); // 地表格 // const grid = new THREE.GridHelper(500, 100, 0xffffff, 0xffffff); // grid.material.opacity = 0.5; // grid.material.depthWrite = false; // grid.material.transparent = true; // scene.add(grid); // 材质 const environment = new RoomEnvironment(); const pmremGenerator = new THREE.PMREMGenerator(renderer); scene.environment = pmremGenerator.fromScene(environment).texture; // 加载 glb 格式的 3D 模型 const loader = new GLTFLoader(); loader.load( url, (gltf: any) => { // 加载成功后的回调函数 const model = gltf.scene; // model.scale.set(0.8, 0.8, 0.8); // 缩小模型 const box = new THREE.Box3().setFromObject(model); const center = box.getCenter(new THREE.Vector3()); model.position.sub(center); // 将模型位置移到原点处 scene.add(model); }, (xhr: any) => { // 加载过程中的回调函数 console.log((xhr.loaded / xhr.total) * 100 + "% loaded"); }, (error: any) => { // 加载失败的回调函数 console.error("Failed to load model", error); } ); // 渲染场景 const animate = () => { //动画帧 animateId = requestAnimationFrame(animate); renderer.render(scene, camera); }; animate(); });
- 销毁,组件销毁清除渲染动画,减少不必要的调用
// 销毁场景 onUnmounted(() => { cancelAnimationFrame(animateId); });