这篇博客是我读ThreeJS官网的Examples总结出来的有用的资料,就当是给自己做个笔记备份了,供大家一起学习参考,这篇文章会随着我不断阅读这些案例进行更新。大家可以持续关注! 版本:r139
1、模型复制
当需要一个模型多次,我们可以选择不加载(load)多次,可以选择加载一次进行复制,从而极大的提高性能。
import * as SkeletonUtils from './jsm/utils/SkeletonUtils.js'; /// 复制模型的脚本
const model1 = SkeletonUtils.clone( gltf.scene ); /// 导入模型后进行多次clone
2、生成一个高亮环境
这个类似与HDR效果,threejs底层实现并封装了该工具,利用该工具,可以在环境中不使用任何灯光也能达到之前的效果(配合灯光使用,效果会更好)
import { RoomEnvironment } from './jsm/environments/RoomEnvironment.js'; // 导入模型的材质文件
const pmremGenerator = new THREE.PMREMGenerator( renderer );
scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture;
3、模块标识符映射
<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'; /// 这个js文件可以会直接使用映射后的路径
</script>
4、动画的使用 首先导入带有动画的模型
const clock = new THREE.Clock(); /// 创建一个时钟对象
const mixer = new THREE.AnimationMixer( model ); // 动画混合器是用于场景中特定对象的动画的播放器
mixer.clipAction( gltf.animations[ 0 ] ).play(); // 指定第一个动画进行播放
animate();
在animate中让动画混合器不断更新
const delta = clock.getDelta(); // 获得前后两次执行该方法的时间间隔
mixer.update( delta ); // 每过这么多秒更新动画
5、电影摄影机(CinematicCamera )
import { CinematicCamera } from './jsm/cameras/CinematicCamera.js';
6、layers层次系统 从用法角度,大家不用管mask(掩码)的变化。一共有0-31层,.set(0)属性就是设置到第几层,默认值是0
enableAll方法: camera.layers.enableAll(); // camera的 出现在0-31所有层
toggle方法: camera.layers.toggle( 1 ); // 把第一层的取反,如果第一层是显示的,toggle(1)后就是不显示第一层,如果第一层是不显示的,toggle(1)后就是显示第一层
disableAll: camera.layers.disableAll(); // camera不出现在任意层
层次系统的所有方法适用于所有场景中的对象
7、模型压缩
import { DRACOLoader } from './jsm/loaders/DRACOLoader.js'; // 可用于导入压缩后的模型
const dracoLoader = new DRACOLoader();
dracoLoader.setDecoderPath( 'js/libs/draco/gltf/' ); // 解压压缩模型的相关js文件路径
const loader = new GLTFLoader(); loader.setDRACOLoader( dracoLoader ); //设置DRACOloader
下面就是常规的loader.load加载模型就行啦。。。
8、性能控件
import Stats from './jsm/libs/stats.module.js';
const stats = new Stats();
container.appendChild( stats.dom );
在animate中
stats.update();
9、控制面板
import { GUI } from './jsm/libs/lil-gui.module.min.js';
let = new GUI(); /// 可选 gui.width = 350;
let folder = gui.addFolder( 'Scene' ); /// 名字层级结构:Scene ---> wireframe/texture
/// 传入初始状态data
folder.add( data, 'wireframe', false ).onChange( funxxx函数 ); /// 初始为没勾选
folder.add( data, 'texture', false ).onChange( funxxx函数 );
folder.open(); /// 初始为看展目录
10、估算模型占内存容量
import * as BufferGeometryUtils from './jsm/utils/BufferGeometryUtils.js';
BufferGeometryUtils.estimateBytesUsed( mesh.geometry ) /// 单位是byte
11、模型裁剪
// 平面裁剪模型指的是存在一个平面, 能够对场景中的物质进行截断, 这个平面就是裁剪平面, 裁剪平面分为全局的裁剪和局部裁剪
原理就是 空间中所有的物体与平面clippingPlanes点积为负的点将不显示。plane是一个数组,默认值是空
// 局部裁剪:是指的有一个平面裁剪裁剪指定物体, 这需除了在render中设置还要在指定物体的material中设置
const localPlane = new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 0.8 ); // 裁剪平面的的裁剪方向 和 从原点到平面的距离 .constant就是第二个属性值
// ***** Clipping setup (material): *****
clippingPlanes: [ localPlane ],
clipShadows: true /// 是否需要对影子进行裁剪,控制这个的值
renderer.localClippingEnabled = true; // 这个设置为true后才能局部截断,控制这个的值
// 全局裁剪指的有一个平面裁剪了整个场景的物体,这里只需要在render中设置
const globalPlane = new THREE.Plane( new THREE.Vector3( - 1, 0, 0 ), 0.1 ); // 裁剪平面的的裁剪方向 和 从原点到平面的距离 .constant就是第二个属性值
renderer.clippingPlanes =[ globalPlane ]; /// 其实只需要设置这一样就能达到裁剪的效果 全局与局部设置material无关
12、第一视角控件
//// left click: forward, right click: backward
import { FirstPersonControls } from './jsm/controls/FirstPersonControls.js';
let controls = new FirstPersonControls( camera, renderer.domElement );
controls.movementSpeed = 5000; /// 前进后端的移动速度
controls.lookSpeed = 0.01; // 转向速度,这个值小一点,不然容易晕
animate 中 controls.update( delta );
13、 geometry_dynamic
const position = geometry.attributes.position; /// 获取plane中所有的点
for ( let i = 0; i < position.count; i ++ ) {
const y = 35 * Math.sin( i / 5 + ( time + i ) / 7 );
position.setY( i, y );
}
position.needsUpdate = true;
写着写着就留下了伤心的眼泪 (≧0≦)呀~~~
其他地方找到我:
知乎:www.zhihu.com/people/berl…
博客园:www.cnblogs.com/berlinss/