three.js examples------LittlestTokyo

131 阅读1分钟

雄关漫道真如铁,而今迈步从头越,一步一步学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>