Three.js 导入模型demo分析(随笔记)

demo来源(如果觉得有用请点赞,如果收藏更好了 谢谢各位)

本期为github拉取Three.js源代码中的对引入glb格式的模型demo分析

clone地址:[email protected]:mrdoob/three.js.git

demo目录:examples\webgl_animation_keyframes

源代码如下 (下方我会对源代码进行逐条分析)

javascript 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
	<title>three.js webgl - animation - keyframes</title>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
	<link type="text/css" rel="stylesheet" href="main.css">
	<style>
		body {
			background-color: #bfe3dd;
			color: #000;
		}

		a {
			color: #2983ff;
		}

	</style>
</head>

<body>

	<div id="container"></div>

	<div id="info">
		<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> webgl - animation - keyframes<br />
		Model: <a href="https://artstation.com/artwork/1AGwX" target="_blank" rel="noopener">Littlest Tokyo</a> by
		<a href="https://artstation.com/glenatron" target="_blank" rel="noopener">Glen Fox</a>, CC Attribution.
	</div>

	<!-- Import maps polyfill -->
	<!-- Remove this when import maps will be widely supported -->
	<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>

	<script type="importmap">
		{
				"imports": {
					"three": "../build/three.module.js"
				}
			}
		</script>

	<script type="module">

		import * as THREE from 'three';

		import Stats from './jsm/libs/stats.module.js';

		import { OrbitControls } from './jsm/controls/OrbitControls.js';
		import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js';

		import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
		import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';

		let mixer;

		const clock = new THREE.Clock();
		const container = document.getElementById( 'container' );
		const stats = new Stats();
		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 );
		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;
		controls.enableDamping = true;

		const dracoLoader = new DRACOLoader();
		dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' );
		const loader = new GLTFLoader();
		loader.setDRACOLoader( dracoLoader );
		loader.load( 'models/gltf/Horse.glb', function ( gltf ) {

			const model = gltf.scene;
			model.position.set( 1, 1, 0 );
			model.scale.set( 0.01, 0.01, 0.01 );
			scene.add( model );

			mixer = new THREE.AnimationMixer( model );
			mixer.clipAction( gltf.animations[ 0 ] ).play();

			animate();

		}, undefined, function ( e ) {

			console.error( e );

		} );


		window.onresize = function () {

			camera.aspect = window.innerWidth / window.innerHeight;
			camera.updateProjectionMatrix();

			renderer.setSize( window.innerWidth, window.innerHeight );

		};


		function animate() {

			requestAnimationFrame( animate );

			const delta = clock.getDelta();

			mixer.update( delta );

			controls.update();
			stats.update();

			renderer.render( scene, camera );

			console.log( delta );
			console.log( mixer.update( delta ) );

}

		</script>

</body>

</html>

demo效果图

代码逐条分析

导入three库

javascript 复制代码
	import * as THREE from 'three';

导入一个性能查看插件 这个东西基本项目上不会用到,用于分析 这个东西就是效果图右上角的 如下图

javascript 复制代码
		import Stats from './jsm/libs/stats.module.js';

导入一个 轨道控制器:也称相机视角控制器(具体使用下文会有介绍)

javascript 复制代码
		import { OrbitControls } from './jsm/controls/OrbitControls.js';

导入模型的材质文件。

javascript 复制代码
		import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js';

分别导入模型格式所需的loader文件。如果需要导入其余模型格式,可在上文的git源码中找到

javascript 复制代码
		import { GLTFLoader } from './jsm/loaders/GLTFLoader.js';
		import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';

创建一个时钟对象Clock**(将用于demo中的小车运动)**

javascript 复制代码
		const clock = new THREE.Clock();

这里获取了container元素。并赋值给了变量container new一个性能查看的插件 添加到了元素上

javascript 复制代码
		const container = document.getElementById( 'container' );
		const stats = new Stats();
		container.appendChild( stats.dom );

设置three的渲染为webGL并赋值给了变量renderer 对renderer的详细设置看注释

javascript 复制代码
	const renderer = new THREE.WebGLRenderer( { antialias: true } );
		// 像素比设置
		renderer.setPixelRatio( window.devicePixelRatio );
		// 渲染容器大小设置
		renderer.setSize( window.innerWidth, window.innerHeight );
		// 在导入材质时,会默认将贴图编码格式定义为Three.LinearEncoding,故需将带颜色信息手动指定为Three.sRGBEncodin
		renderer.outputEncoding = THREE.sRGBEncoding;//材质

将randerer元素添加到了 container中。 生成一个亮度环境,传入renderer 并赋值给了pmremGenerator Scene:生成为场景对象。 设置scene场景对象的背景颜色

javascript 复制代码
// 添加渲染容器到html盒子中
		container.appendChild( renderer.domElement );
		const pmremGenerator = new THREE.PMREMGenerator( renderer );
		const scene = new THREE.Scene();
		scene.background = new THREE.Color( 0xbfe3dd );

此处用到了导入的模型。RoomEnvironment.js文件感兴趣的同学可以去分析文件目录如下

javascript 复制代码
examples\jsm\environments
javascript 复制代码
	import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js';
	...
	...
	scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture;

接下来为设置摄像机 PerspectiveCamera 函数共有4个参数 数据类型均为number PerspectiveCamera( fov, aspect, near, far );

  1. fov------fov表示视场,所谓视场就是能够看到的角度范围,人的眼睛大约能够看到180度的视场,视角大小设置要根据具体应用,一般游戏会设置60~90度。 默认值45
  2. aspect------aspect表示渲染窗口的长宽比,如果一个网页上只有一个全屏的canvas画布且画布上只有一个窗口,那么aspect的值就是网页窗口客户区的宽高比 window.innerWidth/window.innerHeight
  3. near------near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1
  4. far------far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值1000 new一个PerspectiveCamera 设置参数并设置其初始视角

往下OrbitControls 导入的通用的OrbitControls相机控制器并设置其属性值

javascript 复制代码
		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.update();
				// 是否禁止右键拖拽
		controls.enablePan = false;
		controls.enableDamping = true;

导如loader模型。代码每一步都有注释 loader.load函数接收参数,分别问。模型地址。渲染函数,也可以接收错误信息,打印出来查看具体错误

javascript 复制代码
		// 导入DRACO格式的loader
		const dracoLoader = new DRACOLoader();
		// 设置loader路径解压压缩模型
		dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' );
		// 导入GLTF格式的loader
		const loader = new GLTFLoader();
		//设置DRACOloader
		loader.setDRACOLoader( dracoLoader );
		// 导入
		loader.load( 'models/gltf/LittlestTokyo.glb', function ( gltf ) {

			const model = gltf.scene;
			model.position.set( 1, 1, 0 );
			model.scale.set( 0.01, 0.01, 0.01 );
			scene.add( model );

			mixer = new THREE.AnimationMixer( model );
			mixer.clipAction( gltf.animations[ 0 ] ).play();

			animate();

		}, undefined, function ( e ) {

			console.error( e );

		} );

动画执行函数 重复执行animate 函数获取时间更新renderer

javascript 复制代码
		function animate() {

			requestAnimationFrame( animate );
	// 获得前后两次执行该方法的时间间隔
			const delta = clock.getDelta();

			mixer.update( delta );

			controls.update();
			// 性能控件更新
			stats.update();

			renderer.render( scene, camera );

}

至此全文结束

相关推荐
逃逸线LOF20 分钟前
CSS之网页元素的显示与隐藏(旧土豆网遮罩案例)
前端·css
_xaboy35 分钟前
开源表单设计器FcDesigner配置多语言教程
前端·vue.js·低代码·开源·表单设计器
文艺倾年1 小时前
【系统架构师】2025论文《WEB系统性能优化技术》
前端·性能优化·系统架构
铃木隼.1 小时前
Web技术与Nginx网站环境部署
前端·nginx·php
郭尘帅6661 小时前
Vue3 父子组件传值, 跨组件传值,传函数
前端·javascript·vue.js
charlee441 小时前
使用Vite创建一个动态网页的前端项目
前端·javascript·vite
SnowDreamXUE2 小时前
快速搭建一个electron-vite项目
前端·electron
gxn_mmf2 小时前
典籍知识问答模块AI问答bug修改
前端·javascript·后端·bug
说码解字3 小时前
Kotlin 协程
java·前端·kotlin