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 );

}

至此全文结束

相关推荐
SunTecTec31 分钟前
Flink Docker Application Mode 命令解析 - 修改命令以启用 Web UI
大数据·前端·docker·flink
拉不动的猪2 小时前
前端常见数组分析
前端·javascript·面试
小吕学编程2 小时前
ES练习册
java·前端·elasticsearch
Asthenia04122 小时前
Netty编解码器详解与实战
前端
袁煦丞2 小时前
每天省2小时!这个网盘神器让我告别云存储混乱(附内网穿透神操作)
前端·程序员·远程工作
一个专注写代码的程序媛3 小时前
vue组件间通信
前端·javascript·vue.js
一笑code3 小时前
美团社招一面
前端·javascript·vue.js
懒懒是个程序员4 小时前
layui时间范围
前端·javascript·layui
NoneCoder4 小时前
HTML响应式网页设计与跨平台适配
前端·html
凯哥19704 小时前
在 Uni-app 做的后台中使用 Howler.js 实现强大的音频播放功能
前端