目录

1. threejs介绍

2. thresjs的使用

3. 组件介绍

4. threejs的动画

5. 参考资料


前几天在网上看到一个threejs的实现的web 3d的动画,很炫酷,所以特地去了解了一下threejs。我们首先看下官方使用threejs实现的效果:

threejs 隐藏axesHelper threejs效果_3D

 

1. threejs介绍

threejs是基于原生WebGL API和着色器封装得到的3D引擎,也就是一个.js库。直接通过原生WebGL直接编写程序,会比较麻烦,所以threejs就对WebGL做了一层封装,这样方便web开端的去开发web 3d的应用。

所以WebGL是threejs的基础,简单的项目一般也用不到底层WebGL知识,不过学习WebGl有助于深入理解threejs,如果使用Three.js开发项目需要自定义着色器的时候,肯定也是要学习底层WebGL和着色器GLSL知识。

2. thresjs的使用

首先我们看下我们实现的示例效果,实现一个可以鼠标操作的圆柱体:

threejs 隐藏axesHelper threejs效果_点光源_02

代码实现:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>My first three.js app</title>
    <style>
        body { margin: 0; }
    </style>
</head>
<body>
<script src="js/three.js"></script>
<script src="js/OrbitControls.js"></script>
<script>

    /**
     * 场景对象创建
     */
    const scene = new THREE.Scene();
    
    /**
     * 立方体几何对象Geometry
     */
    const geometry = new THREE.BufferGeometry(); //创建一个Buffer类型几何体对象
    //类型数组创建顶点数据
    const vertices = new Float32Array([
        0, 0, 0,        //顶点1坐标
        50, 0, 0,       //顶点2坐标
        0, 100, 0,      //顶点3坐标
        0, 0, 10,       //顶点4坐标
        0, 0, 100,      //顶点5坐标
        50, 0, 10,      //顶点6坐标
    ]);
    // 创建属性缓冲区对象
    const attribue = new THREE.BufferAttribute(vertices, 3); //3个为一组,表示一个顶点的xyz坐标
    // 设置几何体attributes属性的位置属性
    geometry.attributes.position = attribue;

    /**
     * 材质对象
     */
    const material = new THREE.MeshBasicMaterial({
        color: 0x0000ff,            //三角面颜色
        side: THREE.DoubleSide      //两面可见
    });

    /**
     * 网格模型对象Mesh,通过几何对象和几何对象的材质构造
     */
    const cube = new THREE.Mesh(geometry, material);
    scene.add( cube );
    
    /**
     * 辅助坐标系  参数250表示坐标系大小,可以根据场景大小去设置
     */
    var axisHelper = new THREE.AxesHelper(250);
    scene.add(axisHelper);

    /**
     * 光源设置
     */
    //点光源1
    var point = new THREE.PointLight(0xffffff);
    point.position.set(400, 200, 300); //点光源位置
    scene.add(point); //点光源添加到场景中
    // 点光源2  位置和point关于原点对称
    var point2 = new THREE.PointLight(0xffffff);
    point2.position.set(-400, -200, -300); //点光源位置
    scene.add(point2); //点光源添加到场景中
    //环境光
    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient);

    /**
     * 相机设置
     * @type {PerspectiveCamera}
     */
    var width = window.innerWidth;              //窗口宽度
    var height = window.innerHeight;            //窗口高度
    var k = width / height;                     //窗口宽高比
    var s = 500;                                //三维场景显示范围控制系数,系数越大,显示的范围越大
    //创建相机对象
    const camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    // const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
    camera.position.set(200, 300, 200);             //设置相机位置
    camera.lookAt(scene.position);                  //设置相机方向(指向的场景对象)
    // camera.position.z = 5;

    /**
     * 渲染器
     */
    /* WebGLRender */
    const renderer = new THREE.WebGLRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
    document.body.appendChild( renderer.domElement );

    /**
     * 手动操作
     * */
    function render(){
        renderer.render(scene,camera);
    }

    render()

    var controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.addEventListener('change', render);//监听鼠标、键盘事件
</script>
</body>
</html>

代码中已经添加了很详细的注释,我们主要说一下主要的构成:

  • 1. 场景(Scene)构成: 场景主要分网格模型(Mesh)和光源(Light)。网格模型主要是用来构造场景中几何体结构的,我们可是用各种几何题搭建一个整个的框架结构, 而材料则是更像web中的样式,给几何去构建颜色,透明度等。 另外一个是光源, 光源就相当于我们给上述网格模型来增加明暗程度, 当我们给他增加更强的光源时,它应该就变的更亮了。在3D结构中,不同的光照有不同的明暗阴影效果,才能显示空间立体感。 代码中我们通过创建了相应的网格模型Mesh和光源(Light),添加到Scene的对象来构建
  •  相机(Camera):相机主要为场景中的机构提供一种视角。场景已经构建为3D的模型,而3D结构是三位的立体场景,人眼直线也看不到每个面的情况,所以这里提供的Camera是提供了一个观看的视角,通过不同的相机的视角,我们可以从不同的位置,不同的视线方向去看到三维立体结构的不同方位,不同距离做产生的效果。这个就像我们实际使用相机差不多,我们要拍一个图片,就需要选择不同的位置和角度。
  • 渲染器(Render):  通过上面的场景和相机我们已经构建出了虚拟的三位立体场景,相机的位置和角度也设置好了,那么剩下就是拍照了。拍照就相当于是在二维的web平面上去展示3D的立体效果在某个视角的一个图片效果。当我们换一个视角,渲染器也不会有不同的投影效果。

参考一下文末资料的渲染过程图:

threejs 隐藏axesHelper threejs效果_点光源_03

3. 组件介绍

   我们已经大概知道threejs的一个构建过程和渲染流程。通过上面的示例,整个程序的构成如下图(参考资料图片):

threejs 隐藏axesHelper threejs效果_WebGL_04

 在上面的示例中,我们通过上述的这些组件构建了一个threejs的3d应用, 而后续学习也主要是围绕该组件中的各个结构去展开。

4. threejs的动画

threejs中动画分为两种: 1. api提供的周期性动画,2. 基于手动操作的动画

api提供的周期动画主要是按周期,定时的去刷新或者变换某些属性,例如旋转角之类。我们可以自己使用js的定时器实现,也可借助requestAnimationFrame的实现。

基于手动操作的动画,主要是在响应用户操作的使用,根据用户操作结果,来某些属性的变换和刷新。例如上面的示例中,我们使用了一种根据实际用户操作来响应的动作,物体会根据实际拖动去旋转。上面我们使用官方示例提供的一个操作库: