雄关漫道真如铁,而今迈步从头越,一步一步学three,但且相信量变引起质变,追风赶月莫停留,平芜尽处是春山,一步一步来。
<template>
<div id="container"></div>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import * as THREE from 'three';
// 性能监控
import Stats from 'three/examples/jsm/libs/stats.module.js';
// 轨道控制器
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// 引入环境
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment.js';
// 模型加载器
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
// 模型解压器
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
const mixer = ref();
onMounted(() => {
// 创建一个clock对象,用于获取一些时间数据,Clock本质上就是对Date进行封装
const clock = new THREE.Clock();
const container = document.getElementById('container');
const stats = new Stats();
stats.dom.style.position = 'relative';
container?.appendChild(stats.dom);
// 创建一个渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true // 设置防锯齿
});
// 设置渲染器的像素比列
renderer.setPixelRatio(window.devicePixelRatio)
// 设置渲染的尺寸
renderer.setSize(window.innerWidth, window.innerHeight)
// 设置渲染的输出格式
renderer.outputEncoding = THREE.sRGBEncoding;
container?.appendChild(renderer.domElement);
// 创建一个PMREMGenerator,从立方体映射环境纹理生成预过滤的 Mipmap 辐射环境贴图,允许根据材料粗糙度快速访问不同级别的模糊
const pmremGenerator = new THREE.PMREMGenerator(renderer);
// 创建一个场景
const scene = new THREE.Scene();
// 设置背景色
scene.background = new THREE.Color(0xbfe3dd);
// 设置场景的纹理,从提供的场景中生成纹理
scene.environment = pmremGenerator.fromScene(new RoomEnvironment(), 0.04).texture;
// 创建相机并设置位置
const camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 100)
camera.position.set(5, 2, 8);
// 设置轨道控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.target.set(0, 0.5, 0);
controls.update();
controls.enablePan = false; // 当设置为false时,控制器将不会响应用户的操作。默认值为true。
controls.enableDamping = true; // 开启阻尼
// 创建解压器并设置路径
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath('node_modules/three/examples/jsm/libs/draco/gltf/');
// 创建模型加载器并加载模型
const loader = new GLTFLoader();
loader.setDRACOLoader(dracoLoader);
loader.load('models/gltf/LittlestTokyo.glb', gltf => {
const model = gltf.scene;
// 设置模型的位置
model.position.set(1, 1, 0);
// 设置视角
model.scale.set(0.01, 0.01, 0.01);
// 将模型添加到场景中
scene.add(model);
// 创建一个动画混合器
mixer.value = new THREE.AnimationMixer(model);
// 设置剪辑动画 动画
mixer.value.clipAction(gltf.animations[0]).play();
// 执行
animate();
}, undefined, function (e) {
console.error(e);
})
// 动画执行函数
const animate = () => {
// 调用动画帧执行动画
requestAnimationFrame(animate);
// 获得两帧的时间间隔
const delta = clock.getDelta();
// 更新动画混合器、轨道控制器、性能监听器
mixer.value.update(delta);
controls.update();
stats.update();
// 重新渲染
renderer.render(scene, camera);
};
})
</script>
<style>
body {
background-color: #bfe3dd;
color: #000;
}
</style>