Three.js学习总结-入门

5,951 阅读4分钟
      目前现代浏览器越来越普及,web 3D开发也变得流行起来。3D给用户带来的是一种全新的体验,展示酷炫的视觉效果。Three.js是一个javascript 3D库,大大方便了web 3D开发。我在学习中参考了webgl中文网上的 Threejs基础教程,下面正式开始:

介绍和应用

在浏览器里展示3D场景和模型主要是使用WebGL协议,Threejs是一个“Javascript 3D library”,它对WebGL提供的接口进行了封装,降低了学习成本并提升了开发效率。web 3D主要应用于几个方面:
  • web 3D游戏  示例
  • 产品详情展示 示例
  • 仿真模型(地理模型)示例
  • VR & AR 

 搭建环境和demo示例

1. 通过script标签来引入three.js
下载Three.js库并放进项目目录中引入,下载链接
或引入Three.js第三方cdn

<script src="https://cdn.bootcss.com/three.js/r83/three.js"></script>
2. 通过模块来引入

安装npm包   

  npm i three
导入模块

import { Scene } from 'three'; 
const scene = new Scene();
...
导入部件(如果需要)

import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
3. 下面通过官网的例子说明一下开发步骤:
(1)创建场景,在Threejs中场景只有一种 ,使用new 创建一个场景实例

var scene = new THREE.Scene();
(2)创建相机 ,相机是3d场景中的角度,在三维空间中代表观察者所在的位置。在Threejs中有多种相机 呈现的不同效果,主要有透视相机(THREE.PerspectiveCamera)和 正相交相机 (THREE.OrthographicCamera)

var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5; // 设置相机相对物体的坐标
(3)创建渲染器 ,指定在页面某个元素上面渲染

var renderer = new THREE.WebGLRenderer(); 
renderer.setSize( window.innerWidth, window.innerHeight );  // 设置渲染范围
document.body.appendChild( renderer.domElement );
(4)添加物体到场景 ,这里先创建一个立方体然后添加到场景里

var geometry = new THREE.BoxGeometry( 1, 1, 1 ); // 物体形状
var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); // 材质
var cube = new THREE.Mesh( geometry, material ); 
scene.add( cube );
(5)渲染场景 ,结合场景和相机会得到一个画面,将画面渲染到浏览器中,
renderer.render( scene, camera );
这时物体在空间里是静止不同的,结合浏览器循环方法requestAnimationFrame会在每次刷新时调用,每次循环改变物体形态,就会展示动画效果

function animate() { 
    cube.rotation.x += 0.1;
    cube.rotation.y += 0.1;  // 物体旋转
    requestAnimationFrame( animate ); 
    renderer.render( scene, camera ); 
} 
animate(); 
Threejs的基本要素包括场景、相机、光、物体等,逐一介绍。

物体- 形状和材质

上面的代码中创建了一个物体 cube,在Threejs中物体由形状和材质构成,形状顾名思义就是在web 3d世界中展示的形态,通过geometry表示;材质用于展示物体的颜色,纹理,反光等信息,通过material表示。上面的new THREE.BoxGeometry( 1, 1, 1 ),创建了一个长宽高各为1的长方形。而new THREE.MeshBasicMaterial( { color: 0x00ff00 } ),表示这个长方体是自发光绿色的。最后根据形状和素材,new THREE.Mesh( geometry, material ),生成需要显示的物体。

形状类别:

1.BoxGeometry--长方体

2.CylinderGeometry--圆柱体

3.CircleGeometry--圆形平面

4.PlaneGeometry--方形平面

6.SphereGeometry--球体

7.TextGeometry--文字

。。。 具体可查看官网列举和示例代码

材质类别:

1.MeshBasicMaterial -- 自发光材质

2.MeshLambertMaterial--漫反射材质

3.MeshPhongMaterial--镜面反射材质

。。。 常用的三种材质,其中2,3是模拟现实中物体的材质,取决于场景光线的位置,具体可查看官网列举和示例代码

处理使用颜色展示材质外还可以设置纹理使物体更加真实,纹理通过TextureLoader加载纹理图片:

var texture = new THREE.TextureLoader().load( 'textures/crate.gif' );
var geometry = new THREE.BoxBufferGeometry( 200, 200, 200 );
var material = new THREE.MeshBasicMaterial( { map: texture } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );


动画

之前我们使用浏览器循环方法requestAnimationFrame 来实现动画效果,这种方法比setInterval更加精确,但要复杂的动画还需要另外代码实现。可以使用一个动画库tweenjs来实现, tweenjs是一个JavaScript 补间动画库,需要传递要修改的值、动画结束时的最终值和动画花费时间(duration),tweenjs 会以平滑的方式修改元素的属性值。下面进行改造:

import TWEEN from '@tweenjs/tween.js'
...
letcoords = { x: 0, y: 0 }; // 初始值
let tween = new TWEEN.Tween(coords)
.to({ x: 300, y: 200 }, 300000) // 最终值,时间
.easing(TWEEN.Easing.Quadratic.Out) // 缓动函数
.repeat(100) // 重复次数
.onUpdate(function() {  // 更新后回调
    cube.rotation.x = coords.x;
    cube.rotation.y = coords.y;
}).start(); 
var animate = () => { 
    TWEEN.update(); // 执行更新
    requestAnimationFrame( animate ); 
    renderer.render( scene, camera ); 
};
animate()