demo来源(如果觉得有用请点赞,如果收藏更好了 谢谢各位)
本期为github拉取Three.js源代码中的对引入glb格式的模型demo分析
clone地址:git@github.com:mrdoob/three.js.git
demo目录:examples\webgl_animation_keyframes
源代码如下 (下方我会对源代码进行逐条分析)
<!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*asTHREEfrom'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 =newTHREE.Clock();const container = document.getElementById('container');const stats =newStats();
container.appendChild( stats.dom );const renderer =newTHREE.WebGLRenderer({ antialias:true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.outputEncoding =THREE.sRGBEncoding;//材质
container.appendChild( renderer.domElement );const pmremGenerator =newTHREE.PMREMGenerator( renderer );const scene =newTHREE.Scene();
scene.background =newTHREE.Color(0xbfe3dd);
scene.environment = pmremGenerator.fromScene(newRoomEnvironment(),0.04).texture;const camera =newTHREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight,1,100);
camera.position.set(5,2,8);const controls =newOrbitControls( camera, renderer.domElement );// controls.target.set( 0, 0.5, 0 );
controls.update();
controls.enablePan =false;
controls.enableDamping =true;const dracoLoader =newDRACOLoader();
dracoLoader.setDecoderPath('js/libs/draco/gltf/');const loader =newGLTFLoader();
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 =newTHREE.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 );};functionanimate(){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库
import*asTHREEfrom'three';
导入一个性能查看插件 这个东西基本项目上不会用到,用于分析
这个东西就是效果图右上角的 如下图
import Stats from'./jsm/libs/stats.module.js';
导入一个 轨道控制器:也称相机视角控制器(具体使用下文会有介绍)
import{ OrbitControls }from'./jsm/controls/OrbitControls.js';
导入模型的材质文件。
import{ RoomEnvironment }from'./jsm/environments/RoomEnvironment.js';
分别导入模型格式所需的loader文件。如果需要导入其余模型格式,可在上文的git源码中找到
import{ GLTFLoader }from'./jsm/loaders/GLTFLoader.js';import{ DRACOLoader }from'./jsm/loaders/DRACOLoader.js';
创建一个时钟对象Clock(将用于demo中的小车运动)
const clock =newTHREE.Clock();
这里获取了container元素。并赋值给了变量container
new一个性能查看的插件 添加到了元素上
const container = document.getElementById('container');const stats =newStats();
container.appendChild( stats.dom );
设置three的渲染为webGL并赋值给了变量renderer
对renderer的详细设置看注释
const renderer =newTHREE.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场景对象的背景颜色
// 添加渲染容器到html盒子中
container.appendChild( renderer.domElement );const pmremGenerator =newTHREE.PMREMGenerator( renderer );const scene =newTHREE.Scene();
scene.background =newTHREE.Color(0xbfe3dd);
此处用到了导入的模型。RoomEnvironment.js文件感兴趣的同学可以去分析文件目录如下
examples\jsm\environments
import{ RoomEnvironment }from'./jsm/environments/RoomEnvironment.js';......
scene.environment = pmremGenerator.fromScene(newRoomEnvironment(),0.04).texture;
接下来为设置摄像机
PerspectiveCamera函数共有4个参数 数据类型均为number
PerspectiveCamera( fov, aspect, near, far );
- fov——fov表示视场,所谓视场就是能够看到的角度范围,人的眼睛大约能够看到180度的视场,视角大小设置要根据具体应用,一般游戏会设置60~90度。 默认值45
- aspect——aspect表示渲染窗口的长宽比,如果一个网页上只有一个全屏的canvas画布且画布上只有一个窗口,那么aspect的值就是网页窗口客户区的宽高比 window.innerWidth/window.innerHeight
- near——near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1
- far——far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值1000 new一个PerspectiveCamera 设置参数并设置其初始视角
往下OrbitControls导入的通用的OrbitControls相机控制器并设置其属性值
const camera =newTHREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight,1,100);
camera.position.set(5,2,8);const controls =newOrbitControls( camera, renderer.domElement );
controls.update();// 是否禁止右键拖拽
controls.enablePan =false;
controls.enableDamping =true;
导如loader模型。代码每一步都有注释
loader.load函数接收参数,分别问。模型地址。渲染函数,也可以接收错误信息,打印出来查看具体错误
// 导入DRACO格式的loaderconst dracoLoader =newDRACOLoader();// 设置loader路径解压压缩模型
dracoLoader.setDecoderPath('js/libs/draco/gltf/');// 导入GLTF格式的loaderconst loader =newGLTFLoader();//设置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 =newTHREE.AnimationMixer( model );
mixer.clipAction( gltf.animations[0]).play();animate();},undefined,function(e){
console.error( e );});
动画执行函数
重复执行animate 函数获取时间更新renderer
functionanimate(){requestAnimationFrame( animate );// 获得前后两次执行该方法的时间间隔const delta = clock.getDelta();
mixer.update( delta );
controls.update();// 性能控件更新
stats.update();
renderer.render( scene, camera );}
至此全文结束
版权归原作者 Dyz_quite 所有, 如有侵权,请联系我们删除。