终于迎来周末,此前的文章一直围绕 2D、Canvas 和 SVG 展开。在 7 月份,我计划输出三篇万字长文,系统地带领大家学习可视化表达的三种方式:SVG、Canvas 和 WebGL。而这便是第一篇关于 3D 的文章。
读完本篇文章,你将收获以下内容:对 Three.js 框架有一个简单理解并入门;学习 Three.js 中的 Raycaster,主要通过鼠标判断当前选择的物体;以一个简单实例,带领大家用 Three.js 实现简单的可视化地球案例。
一、3D 框架的选择 ——Three.js
- 为何选择 Three.js?
官网对 Three.js 的介绍极为简洁:“Javascript 3D library”。OpenGL 是一个跨平台的 3D/2D 绘图标准,WebGL 则是 OpenGL 在浏览器上的实现。虽然 Web 前端开发人员可以直接使用 WebGL 接口进行编程,但 WebGL 只是非常基础的绘图 API,要求编程人员具备大量数学知识和绘图知识才能完成 3D 编程任务,且代码量庞大。Three.js 对 WebGL 进行了封装,使得前端开发人员即便不懂计算机图形学,只要理解了 Three.js 的一些基本概念,也能轻松进行 Web 3D 开发,降低了门槛,同时大大提升了效率。总结而言,不懂计算机图形学也能借助 Three.js 进行开发。
二、Three.js 的基本要素 —— 场景定义如下:场景是一个三维空间,是所有物品的容器。可以把场景想象成一个空房间,我们可以往里面放置要呈现的物体、相机、光源等。用代码表示为:const scene = new THREE.Scene (); 可以将其想象成一个房间,能够往里面添加各种物体,如正方体、矩形等。实际上,Three.js 中的各种元素之间的关系是一个树形结构。
三、Three.js 的基本要素 —— 相机相机:Three.js 必须往场景中添加一个相机,相机用于确定位置、方向和角度,相机所看到的内容就是我们最终在屏幕上看到的内容。在程序运行过程中,可以调整相机的位置、方向和角度。Three.js 中的相机分为两种,即正交相机和透视相机。接下来为大家一一介绍,但在理解照相机之前,需要先理解一个概念 —— 视椎体。
透视相机:视锥体是摄像机可见的空间,看上去像截掉顶部的金字塔。视锥体由六个裁剪面围成,构成视锥体的四个侧面称为上、下、左、右面,分别对应屏幕的四个边界。为了防止物体离摄像机过近,设置近切面;同时为了防止物体离摄像机太远而不可见,设置远切面。
《Three.js 关键要素详解》一、透视相机视锥体是摄像机可见的空间,形似截掉顶部的金字塔。它由六个裁剪面围成,其中四个侧面称为上、下、左、右面,分别对应屏幕的四个边界。为防止物体离摄像机过近,设置近切面;同时为避免物体离摄像机太远而不可见,设置远切面。
从图中可以看出,由棱台组成的六个面之内的物体是可以被看到的。影响透视照相机大小的因素包括:摄像机视锥体垂直视野角度、摄像机视锥体近端面、摄像机视锥体远端面以及摄像机视锥体长宽比(表示输出图像的宽和高之比)。

在 Three.js 中对应的照相机代码为:const camera = new THREE.PerspectiveCamera (45, width /height, 1, 1000)。透视相机最大的特点是符合人眼观察事物的特点,即近大远小。其背后的实现原理是相机会有一个投影矩阵,该矩阵把视锥体转换成一个正方体,使得远截面的点缩小,近距离的点放大。
二、正交相机正交相机的特点是视锥体为一个立方体。在这种投影模式下,无论物体距离相机远近,在最终渲染的图片中物体的大小都保持不变。这对于渲染 2D 场景或者 UI 元素非常有用。
在 Three.js 中的代码为:const camera = new THREE.OrthographicCamera (width /-2, width / 2, height / 2, height /-2, 1, 1000)。
三、Three.js 的基本要素 —— 网格在计算机世界中,一条弧线是由有限个点构成的有限条线段连接得到的。当线段数量越多,长度越短,达到无法察觉是线段时,就出现了一条平滑的弧线。计算机的三维模型也类似,只不过线段变成了平面,普遍用三角形组成的网格来描述,这种模型称之为 Mesh 模型。
Three.js 背后所有的图形在进行渲染之前,都会进行三角化,然后交给 WebGL 去渲染。Three.js 提供了一些常见的几何形状,有三维的也有二维的,如长方体、球体、长方形、圆形等。如果默认提供的形状不能满足需求,也可以自定义通过定义顶点和顶点之间的连线绘制自定义几何形状,更复杂的模型还可以用建模软件建模后导入。
组成的 mesh 由两个部分组成:材质(Material)和几何体(Geometry)。Three.js 提供了几种有代表性的材质,常用的有漫反射、镜面反射两种材质,还可以引入外部图片,贴到物体表面,成为纹理贴图。
四、Three.js 的基本要素 —— 灯光假如没有光,摄像机看不到任何东西,因此需要往场景添加光源。为了更接近真实世界,Three.js 支持模拟不同光源,展现不同光照效果,有点光源、平行光、聚光灯、环境光等。
- AmbientLight(环境光):环境光会均匀照亮场景中的所有物体,但不能用来投射阴影,因为它没有方向。例如:const light = new THREE.AmbientLight (0x404040); //soft white light。
- 平行光(DirectionalLight):平行光是沿着特定方向发射的光,表现像是无限远,从它发出的光线都是平行的。常用来模拟太阳光的效果。例如:const directionalLight = new THREE.DirectionalLight (0xffffff, 0.5)。
- 点光源(PointLight):从一个点向各个方向发射的光源,常见例子是模拟灯泡发出的光。例如:const light = new THREE.PointLight (0xff0000, 1, 100)。
- 聚光灯(SpotLight):光线从一个点沿一个方向射出,随着光线照射变远,光线圆锥体的尺寸也逐渐增大。例如:const spotLight = new THREE.SpotLight (0xffffff)。还有一些其他的灯光,感兴趣的小伙伴可以自行去 Three.js 官网查看。
更多详情:
https://github.com/wzf1997/blog/issues/8
文章来自深蓝互联http://www.szdbi.com/WEBkaifajishu/535.html转载请注明出处!