在学习 Three.js
之前,感性的了解一些基础的 3D 知识后,后面的学习就不会那么纠结了.
3D 场景前置知识
- 场景(Scene): 场景是[物体,光源等元素]的容器.可以配合
chorme
插件使用,抛出window.scene
对象,即可实时调整和场景相关的所有对象数据,包括物体,光源等. - 相机(Camera): 场景中的相机,代替人眼去观察.一个场景中有且只能有一个相机,一般常用的是透视相机(perspectiveCamera),遵循真实的物理场景法则 -- 远小近大. 还有一个叫正交相机(一般 2D 平面场景游戏使用的比较多,物体的大小和远近无关)
- 物体对象(Mesh): 包括二维物体(点,线,面),三维物体和模型等.
- 光源(Light): 场景中的光源,如果场景中不添加光源,那么整个世界(Scene)将会一片黑暗. 常见的光源包括: 全局光,平行光,点光源(蜡烛).每种光源的表现形式都是不一样的(联想实际生活场景).
- 渲染器(renderer): 场景渲染器. 在基于浏览器的 Three.js 开发模式中,这里就是指的 WebGL ---> Canvas
- 控制器(Control): 通过键盘,鼠标等,可以控制相机的位置,视角等.
下面针对上述的各个点,一个一个的来解释.
场景 (Scene)
场景应该很好理解.
我们生活的地球就是一个场景,场景里有物体(大海,高山,河流,你,我),有光源(太阳光,路灯,手电筒),有摄像机(你的眼镜,路边的监控摄像头)
场景中包含了
- 物体
- 光源
在 Three.js 中,由于我们需要渲染到 HTML 上. 所以这里还多了一个在现实中很难联想的: 渲染器 renderer
相机 (Camera)
有场景了,瞎子是无法看见的.你需要一双可以观察场景的眼镜.
在 Three.js
中, Camera 相机,就是充当眼镜的角色.
不同于真是世界,每个人都有一双眼镜,可以有无数个视角范围. 但是针对某一个人来说,它的视角同时只能有一个.
在 Three.js 中,一个场景中,有且只能有一个相机.
在 Three.js
中,我们常用的相机类型有两种:
- 正交相机(orthographic)
- 透视相机(perspective)
一般情况下,模拟人眼观察的世界(3D),都是使用透视相机(perspective) , 它满足真实世界里的远小近大的规则. 透视相机一般用户渲染 3D 场景
而正交相机的特点是: 物体渲染的尺寸大小和和观察它相机的远近无关.也就是说,在场景中移动一个物体,其大小不会随着镜头的变化而变化. 正交相机一般用于渲染 2D 场景
关于透视相机 API 的大致了解
Three.PerspectiveCamera(fov,aspect,near,far)
参数描述:
-
fov
: 可是范围的角度,也就是视野角度.玩过 fps 游戏的玩家应该都能理解这个参数. 它是一个度数的单位. 一般取值范围在 60 - 90(默认60) , 角度越大,你看的范围也就越宽. -
aspcet
: 渲染区域的纵横比,也可以理解为相机的照射范围的纵横比. 一般取值为window.innerWidth/window.innerHeight
-
near
: 最近镜头距离(比这个还近,相机就照不到 ---> 一般情况下,你看不到你的嘴巴) -
far
: 最远镜头距离(比这个还远,相机就照不到 ---> 一般雾霾天气下,你看不远)
参数的示意图如下:
创建摄像机之后,还要对齐进行定位(人眼在哪?),以及设置观察的角度或者说是方位(往哪看?).
// 伪代码
camera.position = new THREE.Vector3(x,y,z) // 相机在哪
camera.lookAt = new THREE.Vector3(x, y, z) // 往哪看.
灯光 (Light)
如果你呆在过绝对黑暗的地方,你就会发现,没有光源的环境,绝对是一片漆黑.伸手不见五指.
对于 THREE.js
的世界也是如此.
如果不设置光源,你将无法看见你之前设置的任何场景,物体.(有时候,为什么在浏览器里啥都看不见,可以自检一下,是否是没有设置光源,或者光源的颜色就是黑色)
在 THREE.js 中,光源是必须的.如果不设置光源,浏览器的表现形式就是一片漆黑.什么也看不见.
THREE.js
中内置的大量的类型. 可以先联想真实世界,感性的理解一下.
-
AmbientLight
: 环境光. 其颜色会均匀的应用到场景及其所有对象上.这种光源在游戏开发的引擎界里成为为环境光. 这种光没有特定的方向,不会产生阴影. 通常不会把 AmbientLight 作为场景里的唯一光源. 而是和SpotLight
,DirectionalLight
等光源一起结合起来使用,从而达到柔化阴影,增加真是感的效果. 指定坏境光源时要相对保守,例如0x0c0c0c
. 设置太亮或者太暗会导致页面显示效果不佳. -
PointLight
: 3D 空间中的一个点光源,向所有方向发射出光线(蜡烛) -
SpotLight
: 产生圆锥形光柱的聚光灯. 台灯,天花板射灯,游戏里的场景灯都是属于这种光源.. 特别是在你需要使用到阴影的时候. -
DirectionalLight
: 也就是无限光,光线是平行的. 典型的例子就是日光灯.用于模拟遥远的,类似于太阳那样的光源. 该光远和SpotLight
的最大区别在于,无限光(太阳),不会随着距离的变大而变暗. -
HemisphereLight
: 特殊光源. 用于创建户外自然光的效果. 此光源模拟物体表面的反光效果. -
AreaLight
: 面光源. 指定一个发光的区域. -
LensFlare
: 不是光源, 用于给光源添加镜头光晕效果.
Mesh
在 THREE.js
中, Mesh 表示物体.
和真实世界一样, 物体是由几何结构(非标准圆形)和表面材质(一看就知道是)组成.
在计算机的2D世界里,一条弧线是有限个点构成有限个线段连接组成的. 当线段的数量足够多时,每一条线段的长度就会越短,短的像一个点,与此同时,你等到的弧线就会越完美.
计算机的 3D 模型世界也是类似. 只不过线段变成了平面,普遍用很多三角型平面拼接而成的网格模型,我们称之为 Mesh.
在 THREE.js
的世界中. 材质 (Material) + 几何体 (Geometry) = Mesh(物体)
Geometry
类似于物体的骨架.
Material
类似于物体的皮肤.
材质的分类
2D 图形
3D 图形
加载外部模型
(对 3D 不熟,对几何体不熟)绝大多数情况下,我们都是使用设计师个我们提供好的 3D 模型文件,让 three.js
来直接加载.(比如某个工厂的厂区的 3D 模型文件)
我们可以根据设计师提供的 3D 文件格式,来选择对应的 loader
, 将外部模型加载进来.
加载外部模型是通过 three.js
的加载器(loader
) 来实现的.
加载器把文本/二进制数据文件转换为 three.js
对象结构.
由于 3D 文件格式有很多, three.js
也提供的对应的 loader
来处理这些差异化的模型文件. 我们要做的仅仅是使用正确的 loader
加载正确的模型文件即可
3D 文件格式和 loader
对应关系如下:
粒子
THREE.Sprite
在WebGlRenderer渲染器中使用THREE.Sprite创建的粒子可以直接添加到scene中。创建出来的精灵总是面向镜头的。即不会有倾斜变形之类透视变化,只有近大远小的变
化。
场景交互
Three.js中并没有直接提供“点击”功能,一开始使用的时候我也觉得一脸懵逼,后来才发现我们可以基于THREE.Raycaster来判断鼠标当前对应到哪个物体,用来进行碰撞检测.