背景介绍
在 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图形,思路大体上都是这样的:
-
构建一个三维空间
- Three中称之为场景(Scene)
-
选择一个观察点,并确定观察方向/角度等
- Three中称之为相机(Camera)
-
在场景中添加供观察的物体
- Three中的物体有很多种,它们都继承自Object3D类
-
将观察到的场景渲染到屏幕上的指定区域
- Three中使用渲染器(Renderer)完成这一工作
本次讲述如何用在React中用three.js制作一个简单的字节跳动的logo,结合实践看一看three.js中的各个部分是怎么配合运作的。
基本概念
Three.js中的坐标系
Three.js 采用右手坐标系
场景 Scene
Three.Scene对象主要用于保存、跟踪所要渲染的物体、光源等渲染所需的对象。换句话说,所有物体和光源需要添加到Scene对象中,three.js才能渲染这些对象。
相机 Camera
Three.js有4种内置的Camera,分别是:
-
立方相机(CubeCamera)
-
正交相机(OrthographicCamera)
-
透视相机(PerspectiveCamera)
-
立体相机(StereoCamera)
其中最常用的是透视相机,透视相机能够让渲染器渲染出具有人眼视觉效果的图像。创建透视相机时,所传入的四个参数分别是fov(视野角度)、aspect(宽高比)、near(近端面)、far(远端面)
渲染器 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),该材质的渲染结果更精确和逼真,但代价是牺牲一些性能。
网格 Mesh
创建一个网格需要一个几何体,以及一个或多个材质。当网格创建好之后,可以将网格添加到场景中用于渲染。
在React中使用
在项目中引入three的方式有很多种,可以选择在React中用ES6 module的方式使用。
直接使用create-react-app创建一个简单的react项目,并做一些简单的路由配置。
three.js目前已经作为一个npm模块发布了,可以通过npm install three安装three,在代码中可以通过import * as THREE from 'three'引入。
步骤
-
准备基础的场景,相机,渲染器。
-
加入光照,使场景亮起来。
-
制作Logo需要的几何体,并选择材质。
-
制作"ByteDance"字样的文字几何体。
-
最后加入控制器,使场景中的相机能够动起来。
这里的步骤结合代码给大家讲述一下。
注意事项
在ES6 module下部分插件代码需要从three/examples/jsm路径下引入。
网上的资料可能不适合当前版本,具体的用法还是以官方文档为准。