JavaScript 3D Library——Three.js入门

759 阅读5分钟

背景介绍

在 Web 中,实现 3D 场景有很多种方法,比如CSS,canvas,WebGL,WebVR 等。不过考虑到灵活性,WebGL应该是第一选择。

OpenGL,WebGL到Three.js

OpenGL大概许多人都有所耳闻,它是最常用的跨平台图形库。

WebGL是基于OpenGL设计的面向web的图形标准,提供了一系列JavaScript API,通过这些API进行图形渲染将得以利用图形硬件从而获得较高性能。

而three.js是通过对WebGL接口的封装与简化而形成的一个易用的图形库。

简单点的说法:WebGL可以看成是浏览器给我们提供的接口,在JavaScript 中可以直接用这些API进行3D图形的绘制;而three.js就是在这些接口上又帮我们封装得更好用一些。

WebGL与Three.js对比

WebGL门槛相对较高,需要相对较多的数学知识。虽然WebGL提供的是面向前端的API,但本质上WebGL跟前端开发完全是两个不同的方向,知识的重叠很少。相关性只是他们都在web平台上,都是用JavaScript 而已。前端工程师想要短时间上手WebGL还是挺有难度的。

于是,three.js对WebGL提供的接口进行了封装,简化了很多细节,大大降低了学习成本。因此,从three.js入手是值得推荐的,这可以让你在较短的学习后就能面对大部分需求场景。

Three.js的学习问题

Three.js的文档对初学者来说有些过于简明扼要,只凭借文档学习有些吃力。

这里推荐一些相对较好的教程:

  • Three.js开发指南(第一版中文版)

该书使用的的three.js是2014年10月29发布的r69版本,书的内容相对有些偏老(最新版r109),不过涉及到的知识框架是一样的。

  • Learning Three.js:The JavaScript 3D Library for WebGL

比较全面地讲解了three.js的各种功能。

Three.js入门

一个典型的 Three.js 程序至少包括 渲染器、场景、照相机、以及场景中创建的物体。

要在屏幕上展示3D图形,思路大体上都是这样的:

  1. 构建一个三维空间

    • Three中称之为场景(Scene)
  2. 选择一个观察点,并确定观察方向/角度等

    • Three中称之为相机(Camera)
  3. 在场景中添加供观察的物体

    • Three中的物体有很多种,它们都继承自Object3D类
  4. 将观察到的场景渲染到屏幕上的指定区域

    • Three中使用渲染器(Renderer)完成这一工作

本次讲述如何用在React中用three.js制作一个简单的字节跳动的logo,结合实践看一看three.js中的各个部分是怎么配合运作的。

image

基本概念

Three.js中的坐标系

Three.js 采用右手坐标系

image

场景 Scene

Three.Scene对象主要用于保存、跟踪所要渲染的物体、光源等渲染所需的对象。换句话说,所有物体和光源需要添加到Scene对象中,three.js才能渲染这些对象。

相机 Camera

Three.js有4种内置的Camera,分别是:

  • 立方相机(CubeCamera)

  • 正交相机(OrthographicCamera)

  • 透视相机(PerspectiveCamera)

  • 立体相机(StereoCamera)

其中最常用的是透视相机,透视相机能够让渲染器渲染出具有人眼视觉效果的图像。创建透视相机时,所传入的四个参数分别是fov(视野角度)、aspect(宽高比)、near(近端面)、far(远端面)

image

渲染器 Renderer

相机的初始化过程中没有与场景绑定,需要用渲染器把他们俩关联起来。这样,相机就拍到了场景里的东西。Three.js中有四种内置的渲染器,本样例使用WebGLRenderer。

光源 Light

Three.js中有许多不同种类的光源,每种光源都有特别的行为和用法。

这里介绍两种光源:

  • 环境光(AmbientLight)该光源的颜色会叠加到场景中现有物体的颜色上。

  • 聚光灯(SpotLight)该光源类似台灯,可以投射阴影。

几何体 Geometry

Three.js提供了很多可以在三维场景中使用的几何体。

创建基础几何体非常简单,比如创建一个立方几何体,只需要传入沿三轴方向的长度。

new THREE.BoxGeometry( 1, 1, 1 ) 

而three.js提供的基础几何体并不能完全满足我们要制作的logo的需求,用多面几何体(PolyhedronGeometry)又显得过于繁琐了。

最后logo的几何体部分选用的高级几何体中的凸面几何体(ConvexGeometry),文字部分选用文本几何体(TextGeometry)。

材质 Material

材质就像物体的皮肤,决定了几何体的外表。例如定义一个几何体看起来是否像金属,是否透明等。在three.js的官方文档中可以看到各种材质的表现效果。

Three.js中能对灯光作出反应的材质并不多,样例中选用标准网格材质(MeshStandardMaterial),该材质的渲染结果更精确和逼真,但代价是牺牲一些性能。

image

网格 Mesh

创建一个网格需要一个几何体,以及一个或多个材质。当网格创建好之后,可以将网格添加到场景中用于渲染。

在React中使用

在项目中引入three的方式有很多种,可以选择在React中用ES6 module的方式使用。

直接使用create-react-app创建一个简单的react项目,并做一些简单的路由配置。

three.js目前已经作为一个npm模块发布了,可以通过npm install three安装three,在代码中可以通过import * as THREE from 'three'引入。

步骤

  1. 准备基础的场景,相机,渲染器。

  2. 加入光照,使场景亮起来。

  3. 制作Logo需要的几何体,并选择材质。

  4. 制作"ByteDance"字样的文字几何体。

  5. 最后加入控制器,使场景中的相机能够动起来。

这里的步骤结合代码给大家讲述一下。

注意事项

在ES6 module下部分插件代码需要从three/examples/jsm路径下引入。

网上的资料可能不适合当前版本,具体的用法还是以官方文档为准。