three.js介绍

three.js三要素
基础三要素:
场景:放置物体的容器
摄像机:想象成人的眼睛,可以提调整位置,角度

渲染器:接收场景和摄像机,计算在浏览器上渲染的最终的2D画面

简单案例-创建一个立方体

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| import * as THREE from 'three';
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
renderer.render( scene, camera );
|

案例摄像机参数

增加一个坐标轴
一定要在renderer.render方法之前增加显示对象
1 2 3
| const axesHelper = new THREE.AxesHelper( 50 ); scene.add( axesHelper ); renderer.render( scene, camera );
|

轨道控制器
现在图形是渲染出来了,但是我想用鼠标进行放大缩小,以及旋转还是不行,这时就要使用到了轨道控制器。
轨道控制器的主要作用是使摄像机围绕目标进行轨道运动
使用方法:
- 单独引入
OrbitControls
轨道控制器构造函数 - 创建轨道控制器
- 在渲染循环中更新场景渲染
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| import * as THREE from 'three'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
const geometry = new THREE.BoxGeometry( 1, 1, 1 );
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
const cube = new THREE.Mesh( geometry, material );
scene.add( cube );
camera.position.z = 5;
const axesHelper = new THREE.AxesHelper( 50 ); scene.add( axesHelper );
const controls = new OrbitControls( camera, renderer.domElement );
function animate() { requestAnimationFrame( animate ); controls.update(); renderer.render( scene, camera ); }
animate()
|
场景自动适配大小
目前场景是在初始化时就已经固定了,如何浏览器窗口大小变化,场景式不跟随变化的,为了解决这个问题,需要进行场景自动适配大小
1 2 3 4 5 6 7 8 9 10 11
| function resize(){ window.addEventListener('resize',()=>{ renderer.setSize( window.innerWidth, window.innerHeight ); camera.aspect = window.innerWidth/window.innerHeight; camera.updateProjectionMatrix(); }) } resize()
|
物体的移动和变换
可以直接移动几何对象geometry.translate(5,0,0)
可以对网格对象进行坐标的重新设置cube.position.x = 10
旋转:cube.rotation.x = Math.PI/4
缩放:cube.scale.z =2
旋转和缩放都是按照自己的坐标系,而不是按照世界坐标系,移动是按照世界坐标系
性能监视器
我们常用的监视器有三个

使用方法
- 单独引入Stats附加组件
- 创建性能监视器
- 设置面板类型(0,1,2)
- 添加到DOM
1 2 3 4
| import Stats from 'three/examples/jsm/libs/stats.module.js'; const sta = new Stats(); sta.showPanel(0) document.body.appendChild(sta.domElement)
|
注意:为了让监视器实时显示,需要实时调用sta.update();
删除物体
three.js是不会自动删除物体的,为了他提高性能,避免内存泄漏,需要手动进行删除。
几何体
几何体常用来表示定义为属性集合的顶点信息,three.js在内部为每一个属性创建一个WebGLBuffer类型的对象。 这些实体仅有在调用BufferGeometry.dispose()的时候才会被删除。
材质
材质定义了物体将如何被渲染。 着色器程序只有在相应材质被废置后(Material.dispose())才能被删除。
注意:将一个mesh(网格)从场景中移除,是不会
删除它的geometry(几何体)和material(材质)
1 2 3 4
| cube.geometry.dispose(); cube.material.dispose(); scene.remove(cube);
|
光线投射
光线投射经常被用来与3D物体的鼠标交互
也就是相机的位置到鼠标点击的位置形成一条射线,该射线会穿过物体,这是就可以对穿过的物体进行操作了

在得到场景中的鼠标的坐标点时,这里面涉及到了坐标的归一话问题,也就是canvas屏幕坐标系需要映射到WebGL坐标系

转换公式

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| function Select(){ const raycaster = new THREE.Raycaster(); const pointer = new THREE.Vector2(); window.addEventListener( 'click', (event) =>{ pointer.x = ( event.clientX / window.innerWidth ) * 2 - 1; pointer.y = - ( event.clientY / window.innerHeight ) * 2 + 1; raycaster.setFromCamera(pointer,camera); const intersects = raycaster.intersectObjects( scene.children ); if(intersects[0]) { scene.remove(intersects[0].object) console.log(intersects[0]) } }); }
|
three.js中文手册