一、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 图片:RGBELoader
new 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),一起交流学习。