一、Three.js 简介

提到 Three.js,不得不先提 OpenGL 和 WebGL,OpenGL 是一个跨平台的3D/2D的绘图规范(标准),WebGL(Web Graphics Library)是一种3D绘图协定。

WebGL容许把JavaScript和OpenGL 联合在一起使用,但应用WebGL原生的API来写3D程序十分的简单,同时须要绝对较多的数学知识,对于开发者来说学习老本十分高。

Three.js是基于webGL的封装的一个易于应用且轻量级的3D库,Three.js对WebGL提供的接口进行了十分好的封装,简化了很多细节,大大降低了学习老本,极大地提高了性能,性能也十分弱小。

(1)Three.js官网

(2)Three.js 的 github 地址

二、起步阶段先从简略开始,间接援用 Three.js,学会最根本的 Three.js 的应用办法

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>Document</title></head><body>  <script src="js/three.min.js"></script>  <script>    // 创立场景    const scene = new THREE.Scene();     // 创立相机,PerspectiveCamera(透视相机),参数(视线角度,长宽比,进截面,远截面)    const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);     // 渲染器    const renderer = new THREE.WebGLRenderer();    // 设置渲染器的宽高    renderer.setSize( window.innerWidth, window.innerHeight );    // 将renderer(渲染器)的dom元素(renderer.domElement)增加到咱们的HTML文档中    document.body.appendChild( renderer.domElement );    // demo--立方体    const geometry = new THREE.BoxGeometry( 1, 1, 1 ); // BoxGeometry 立方体对象    const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );  // MeshBasicMaterial 其中的一种材质,设置色彩绿色    const cube = new THREE.Mesh( geometry, material ); // 创建一个网格对象    scene.add( cube ); // 将网格对象增加到场景中    camera.position.z = 5;         //     function animate() {      requestAnimationFrame( animate ); // 创立了一个使渲染器可能在每次屏幕刷新时对场景进行绘制的循      cube.rotation.x += 0.01; // 使正方体能动起来      cube.rotation.y += 0.01; // 使正方体能动起来      renderer.render( scene, camera );     }    animate();  </script></body></html>

以上代码能够间接运行,运行的成果如下

三、应用 npm 来开发并测试

(1)获取我的项目代码,我的项目的git地址
(2)装置依赖

npm install

(3)开发次要代码 day01.js

// 引入import * as THREE from 'three';import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';// 根底场景三大件const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10);const renderer = new THREE.WebGLRenderer({antialias:true});renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );// 加灯光const ambientLight = new THREE.AmbientLight(0xffffff,0.5);scene.add(ambientLight);// 创立一个盒子const geometry = new THREE.BoxGeometry( 1, 1, 1 );const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );const boxMesh = new THREE.Mesh( geometry, material );scene.add( boxMesh );function animate() {  requestAnimationFrame( animate );  renderer.render( scene, camera ); }animate();

(4)执行 npm run start ,关上 http://localhost:3000/,目前看到的是一片彩色,并未看到盒子展现进去,起因是因为相机的的地位是处在盒子的中心点,此时须要设置相机的地位。

camera.position.set(0.6,0.6,1);

(5)此时指标还不能拖动,须要加上轨道控制器,使得相机围绕指标进行轨道静止,就能看到指标的平面图像了

const controls = new OrbitControls( camera, renderer.domElement );

(6)加载模型,并退出动画播放

new GLTFLoader().load('../resources/donuts.glb',(gltf)=>{  scene.add(gltf.scene);    mixer = new THREE.AnimationMixer(gltf.scene); //AnimationMixer(动画混合器)  const clips = gltf.animations; // 播放所有动画  clips.forEach(function (clip) {    const action = mixer.clipAction(clip);    action.loop = THREE.LoopOnce;    action.play();    // 停在最初一帧,使得动画播完了不会回到初始状态下    action.clampWhenFinished = true;  });})

(7)加载环境光HDR图片:RGBELoader

new RGBELoader().load('../resources/sky.hdr', function (texture) {  texture.mapping = THREE.EquirectangularReflectionMapping;  scene.environment = texture;  renderer.outputEncoding = THREE.sRGBEncoding;  renderer.render(scene, camera);});

(8)残缺 js 代码展现

// 引入import * as THREE from 'three';import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader';// 根底场景三大件const scene = new THREE.Scene();const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10);const renderer = new THREE.WebGLRenderer({antialias:true});renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );let mixer;// 设置相机的地位camera.position.set(0.6,0.6,1);// 轨道控制器,使得相机围绕指标进行轨道静止const controls = new OrbitControls( camera, renderer.domElement );// 加灯光/* const ambientLight = new THREE.AmbientLight(0xffffff,0.5);scene.add(ambientLight); */// 创立一个盒子/* const geometry = new THREE.BoxGeometry( 1, 1, 1 );const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );const boxMesh = new THREE.Mesh( geometry, material );scene.add( boxMesh ); */// 加载模型new GLTFLoader().load('../resources/donuts.glb',(gltf)=>{  // console.log(gltf);  scene.add(gltf.scene);  /* gltf.scene.traverse((child)=>{    console.log(child.name);  }) */  mixer = new THREE.AnimationMixer(gltf.scene); //AnimationMixer(动画混合器)  const clips = gltf.animations; // 播放所有动画  clips.forEach(function (clip) {    const action = mixer.clipAction(clip);    action.loop = THREE.LoopOnce;    action.play();    // 停在最初一帧    action.clampWhenFinished = true;  });})// 加载环境光HDR图片:RGBELoadernew RGBELoader().load('../resources/sky.hdr', function (texture) {  texture.mapping = THREE.EquirectangularReflectionMapping;  scene.environment = texture;  renderer.outputEncoding = THREE.sRGBEncoding;  renderer.render(scene, camera);});function animate() {  requestAnimationFrame( animate );  renderer.render( scene, camera );  controls.update();  if(mixer){    mixer.update(0.02);  }}animate();

(9)成绩展现

四、结束语

能够退出猿创营 (v:dashuailaoyuan),一起交流学习。