ThreeJs初探
这几天想给个人主页加点东西丰富内容,想来在如今成熟的软硬件条件下,现代浏览器对WebGL的支持已经十分完善,所以寻思不如来点3d效果,也借此机会对ThreeJs有个大体的了解。
本文将简单介绍three.js的使用,希望尽量用精简的文字帮助大家快速入门。
ThreeJs介绍
我们知道,WebGL相当于OpenGL的Web版,借助其提供的Api,我们能够在浏览器环境上充分利用硬件加速来渲染3D场景和模型。然而这些Api对一般Web开发人员来说门槛较高,于是three.js应运而生,这是一个基于WebGL封装的轻量易用的第三方js库。
开始上手
官方地址:https://threejs.org/
github:https://github.com/mrdoob/three.js
官方demo
首先访问three.js的github地址,看到其说明中给了一个简单示例,我们把这段代码放到html中,并且引入three.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>three demo</title>
</head>
<body>
</body>
<script src="https://threejs.org/build/three.min.js"></script>
<script>
var camera, scene, renderer;
var geometry, material, mesh;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 1;
scene = new THREE.Scene();
geometry = new THREE.BoxGeometry(0.2, 0.2, 0.2);
material = new THREE.MeshNormalMaterial();
mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
mesh.rotation.x += 0.01;
mesh.rotation.y += 0.02;
renderer.render(scene, camera);
}
</script>
</html>
然后用浏览器打开看看,可以看到一个旋转的正方形,环境就这么跑起来了。
了解概念
我们再来看看示例的这段js代码做了什么,简单归纳如下:
Camera --> Scene --> Renderer --> render
add │ │
Mesh │
│ Animation ─┘
Geometry ─┤
│
Material ─┘
于是这里涉及几个概念:
- 场景(Scene):所有物体的容器,即我们构建的三维世界
- 摄像机(Camera):观察场景的视角,决定3D场景如何投影到画布上
- 渲染器(Renderer):将场景以摄像机投影视角绘制到画布
关于摄像机投影,有以下两种:
- 正交投影:
- 透视投影:
各位可以把自己想象成一名摄影师
代码中的PerspectiveCamera就是透视投影,该方法的四个参数分别为视野角度、宽高比、摄像机允许观察的最近距离、摄像机允许观察的最远距离
再看看另外几个概念:
- 网格(Mesh):计算机世界中弧线是由大量线段连接而成,三维模型也类似,普遍做法是用三角形组成的网格来描述,这就是Mesh模型
- 形状(Geometry):构成模型的形状,threejs提供了盒子(Box)、圆形(Circle)、圆柱体(Cylinder)、球体(Sphere)等基本形状
- 材质(Material):模型表面的材质,包括网格深度材质(MeshDepthMaterial)、网格非发光材质(MeshLambertMaterial)等
入门实践
现在来试下用three.js来构建一个运动的葫芦
创建物体
我们知道葫芦可以看成是一个轴对称图形,于是注意到three.js提供了LatheGeometry(车床模型),它可以用来生成 甜甜圈,管道,花瓶 等围绕Y轴旋转的模型,那么接下来看看怎么用数学函数来表示葫芦的轮廓
......
上面这段纯属瞎掰,用函数来表示葫芦也并非容易,所以这里暂且略过,我们还是直接从网上找个模型来用吧,来看看怎么导入
<!-- 引入objloader.js -->
<script src="./js/OBJLoader.js"></script>
//加载obj文件
var loader = new THREE.OBJLoader();
loader.load(
// obj文件URL
'./hulu.obj',
// 文件加载完成
function (object) {
/* 省略部分代码 */
console.log('object即加载得到的Object3D实例');
},
// 文件加载中
function (xhr) {
console.log((xhr.loaded / xhr.total * 100) + '% loaded');
},
// 加载出错
function (error) {
console.log('An error happened');
}
);
构造场景
然后就是参考前面官方demo的三板斧
- 创建场景
- 摆放摄像机
- 摆放物体
- 准备灯光
详细代码可以参考我放到github上的源码,这里不再详述
创建动画
最后一步,来告诉葫芦要怎么动,就让它绕着一根轴旋转吧
function animate() {
if (mesh) {
requestAnimationFrame(animate);
let axis = new THREE.Vector3(0, 1, 0);
axis.normalize()
// 绕Y轴旋转
mesh.rotateOnAxis(axis, -0.01)
renderer.render(scene, camera);
}
}
好了,现在可以大喊一声Action
把html和其他资源文件放到服务器上后打开即可看到最终效果。
小结
3D是个博大精深的课题,除了计算机,还涉及数学、图形学等多门学科,所以本文也仅做简单介绍,希望能帮助前端开发者有个入门的了解
对于three.js,本人也是初学者,文章如有纰漏之处,还请多多包涵~