THREE.JS是什么?
  Three.js是一个轻量级,跨平台的Javascript库,可以在浏览器上结合HTML5的canvas,SVG或者WebGL,创建和展示3D模型和动画。

  Three.js允许我们在不依赖任何浏览器插件的情况下,创建一个GPU加速的3D动画场景,这可能得益于WebGL的出现,因为WebGL的底层实现是基于OpenGL。

  相信读者看到这篇文章之前,已经被Three.js的魅力所吸引,如果你还不清楚Three.js的能干什么,还没有领会其魅力所在,那么可以去他们的官网,体会一下。

基本概念
  首先我们来介绍介绍一下Three.js的基本概念,其中有三个最重要的概念是渲染器(Render),照相机(Camera),以及场景(Scence), 下面我们通过一个最简单的例子,通过这个例子我们可以很好的解释这个三格概念:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>hello three.js</title>
</head>
<body>
    <script src="https://threejs.org/build/three.js"></script>
    <script>
        var scene = new THREE.Scene();
        var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        document.body.appendChild( renderer.domElement );

        var boxGeometry = new THREE.BoxGeometry(1, 1, 1);
        var material = new THREE.MeshBasicMaterial( { color: 0x999999 } );
        var box = new THREE.Mesh(boxGeometry, material)
        scene.add(box)
        camera.position.z = 5;

        function render() {
            requestAnimationFrame(render)

            box.rotation.x += 0.01
            box.rotation.y += 0.01

            renderer.render( scene, camera )
        }
        render()
    </script>
</body>
</html>

  从上面的例子中我们可以看到,首先我们创建了一个场景scene,一个摄像机camera和一个渲染器renderer,这是我们在页面上看到一些东西最基础的三要素。但是如果仅有这些,我们渲染出的内容是空的。这很容易理解,因为我们仅仅只创建了一个空的场景,就是什么也没有,nothing,你可以想象你处于一个除了你之外什么都没有的宇宙中,那么无论你往任何方向看,都没有东西。无论你以任何速度往任何方向奔跑,也不会有任何变化,甚至你都无法感知你的速度,因为没有参照物,多么可怕的场景。

  为了能够看到东西,我们在后面创造了一个立方体box。那么在3D的世界中,我们是怎么表述一个物体的呢? 我们都知道,我们的世界是由点线面组成,所以在Three.js中也是用点线面组成。在上面的例子中,我们使用BoxGeometry来描述一个立方体的点线面的结构。但是如果仅仅只有点线面的话,物体的任何表面都是绝对光滑和透明的。因此我们要给物体指定不同材质,这样看上去才能显示出物体本来的样子。我们使用MeshBasicMaterial对象来描述一个最基本的材质,上面的例子中,我们仅仅设置了这个材质的颜色为灰色。

  场景创建好,场景里也有了一个物体(立方体)。是不是直接渲染场景就能看到这个立方体了呢?并不是这样的,为什么?一个场景scene就是一个宇宙,这个宇宙广袤无垠,没有边界,在这宇宙里面可能有散落着无限多的物体,分布于宇宙的各个角落,那么我们应该渲染那些物体呢?为了解决这个问题,摄像机camera就登场了,camera就是一个天文望远镜,负责捕获宇宙空间中某一个方向上某一个时刻的画面,并将这一画面保存成一个快照数据。这样我们就知道应该看到那些东西了,如果想看到别处的画面,那么我们就移动或者旋转摄像机就可以了。就好比人类想看到太阳系外面的世界,就只能将探索者1号放出去,一直往逃离太阳系的方向飞行,永不回头。

  现在有了图像数据,我们应该怎么做才能看到图像呢?这时候,渲染器就登场了,渲染器将场景和摄像机唯一确定的画面渲染到屏幕上,这时候宇宙的才能呈现到我们的面前。但是到目前为止,我们只能看到一张宇宙的照片,静止的照片,这个结果肯定不足以吸引我们,这么观察宇宙肯定没有意思。大物理学家牛顿告诉我们:静止是相对的,运动是绝对的。

  所以我们应该想像看电影一样观察运动中的宇宙。怎么做呢?我们都知道,动态的电影其实是由一张张静态的图片快速翻动,让我们产生电影是动态的错觉。但是无所谓,我们需要的就是这个效果。借鉴电影的理论,我们只要按一定时间间隔去截取设摄像机捕捉画面,并且让渲染器渲染出来,只要这个时间间隔合适,我们就能观查到一个运动的宇宙了。

  至此一个宇宙就这么诞生了,但是上面创建的宇宙很简单,只有一个立方体,为了能创造出一个丰富多彩的宇宙,我们还需要到其他更加有趣的概念:
Light: 光源,成像的基本条件,也是营造各种环境效果的工具;
Geometry: 几何体,描述物体的内部骨架;
Material: 材质,描述物体的表面性质,如物体表面的折射率,反射率;
Texture: 纹理,物体表面的花纹图案;
Object: 物体,通过Geometry和Material描述出来一个有骨架又有皮肤的物体;
Audio: 音频播放器;
Shadow: 影子;
Loader: 加载器,用来加载3D模型的工具;
Animation: 动画;

接下来的文章我们针对上面的概念逐一讲解。