先看下面这样一段代码:
const camera = new THREE.PerspectiveCamera(
  55,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
); //定义摄相机
const renderer = new THREE.WebGLRenderer(); // 使用 WebGLRenderer 渲染器,该渲染器会调用电脑显卡进行渲染
renderer.setSize(window.innerWidth, window.innerHeight);
复制代码这段代码中,我们首先定义了一个场景 ( scene )、照相机 ( camera ) 和 渲染器 ( renderer )对象。首先,场景是一个容器,主要用于保存、跟踪所要渲染的物体和使用的光源。如果没有场景,Three.js 就无法渲染任何物体。其次,摄相机决定了能够在场景中看到什么,即屏幕上哪些东西需要渲染。最后,渲染器是基于摄相机的角度来计算场景对象在浏览器中会渲染成什么样子,然后调用底层 API 执行真正的场景绘制工作。可能你会觉得简单,但是就是这样,创建一个场景只需要场景、相机和渲染器三个对象。
- 场景。在 Three.js 中,场景只有一种,就是用 THREE.Scene 来表示。它是所有不同对象的容器,可以用来保存所有图形场景的必要信息。也就是说, THREE.Scene 保存了所有对象、光源和渲染所需的其他对象。例如,你想要显示一个橙子,就需要将橙子这个对象加入到场景中。下面,我们给出一段代码,对场景的功能进行阐述:
const camera = new THREE.PerspectiveCamera(
  55,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
); //定义摄相机
scene.add(camera); // 向场景中添加摄像机
const geometry = new THREE.SphereGeometry(5, 32, 32); // 定义球体
const material = new THREE.MeshBasicMaterial({ color: 0xff9800 }); // 定义材质
const sphere = new THREE.Mesh(geometry, material);
sphere.name = "sphere-" + scene.children.length;
scene.add(sphere); //将球体添加到场景
scene.remove(sphere); //将球体从场景中移除
console.info(scene.children);
复制代码上述代码中,我们分别应用了场景相关方法:
- THREE.Scene.Add: 用于向场景中添加对象,该方法还可以创建对象组;
- THREE.Scene.Remove: 用于移除场景中的对象;
- THREE.Scene.children: 用于获取场景中所有的子对象列表,包括摄像机和光源;
- THREE.Scene.getObjectByName: 利用 name 属性,获取场景中特定的对象;
- 摄相机。在 Three.js 中提供了两种主要的摄像机,分别是正交投影摄像机和透视投影摄像机 (目前还支持了 VR 摄像机)。首先,使用正交投影摄像机 (OrthographicCamera) ,你看到的物体所被渲染的尺寸都是一样的,因为对象相对于摄像机的距离对渲染的结果是没有影响的。这种摄像机通常被用在二维游戏中。下面,我们定义一个正交投影摄像机:
  const camera = new THREE.OrthographicCamera(
  width / -2,
  width / 2,
  height / 2,
  height / -2,
  1,
  1000
);
scene.add(camera);
复制代码正交投影摄像机的参数定义了摄像机”视锥体”的大小。其中,视锥体指定是建模世界中可能出现在屏幕上的空间区域,也就是摄像机的视野。

THREE.PerspectiveCamera 有如下参数:
- fov: 视场,即在摄像机中能够看到的那部分场景。推荐默认值:50。
- aspect: 长宽比。这是渲染结果的横向尺寸和纵向尺寸的比值。推荐默认值: window.innerWidth / window.innerHeight。
- near: 近面距离。定义了从距离摄像机多近的距离开始渲染。通常情况下这个值会设置的尽可能小,这样就能从摄像机的位置看到尽可能多的物体。推荐默认值:0.1。
- far: 远面距离。定义了摄像机从它所处的位置能够看多远。如果这个值设置的较小,那么场景中有一部分不会被渲染;如果设置较大,会影响性能。推荐默认值:1000。
- zoom: 变焦。用于放大或缩小场景。值小于 1,场景被缩小;大于 1,场景被放大。推荐默认值:1。
目前,我们已经介绍了如何创建摄像机,以及摄像机的各个参数。通常来说,摄像机会指向场景的中心,用坐标来表示就是 position(0,0,0) 。同时,我们可以改变摄像机指向的位置: camera.lookAt(new THREE.Vector3(x,y,z));
- 渲染器。Three.js 除了提供基于 WebGL 的渲染器外,还有其他的渲染器,比如基于 HTML canvas 的渲染器、基于 CSS 的渲染器,基于 SVG 的渲染器。但是这些渲染器并不推荐使用,一方面它们十分消耗 CPU 资源,另一方面缺乏对一些功能(如:阴影、材质)的支持。在 Three.js 主要使用 WebGLRenderer() 渲染器,一般会经历如下三个过程:
- 创建渲染器;
- 开始渲染: render(scene, camera);
- 添加到 canvas 对象中;
通过上面对三个概念的讲解,你可以从实际生活中理解。例如实际生活中拍照的例子,渲染器起到的作用就是执行拍照这个动作。
网络模型
几何体、材质、贴图、颜色这些概念属于网络模型( Mesh )的范畴中。
- 几何体 ( Geometry )。前面的代码中,我们已经使用过了几何体。我们可以知道,创建一个立方体的方法是: const box = new THREE.BoxGeometry(50,50,50); ,即我们创建了一个长宽高都是 50 的立方体。像大多数三维库一样, Three.js 中几何体基本上是三维空间中的点(顶点)集和将这些点连接起来的面。例如,一个立方体有 8 个角,每个角都可以用 x,y 和 z 坐标点来定义,所以每个立方体在三维空间中都有 8 个顶点。其次,一个立方体有 6 个面,每个角有一个顶点。在 Three.js 中,每个面都是包含 3 个顶点的三角形。所以,立方体的每个面都是由两个三角形面组成的。当你使用几何体时,不需要自己定义几何体的所有顶点和面。例如,定义立方体只需要定义长、宽、高。 Three.js 会基于这些信息在正确的位置创建一个拥有 8 个顶点和 12 个三角形面的立方体。当然,我们还可以自定义顶点和面来创建几何体:
const vertices= [new THREE.Vector3(1,2,1),...,new THREE.Vector3(-1,-1,1)];
const faces = [new THREE.Face3(0,2,1),...,new THREE.Face3(3,6,4)];
const geometry = new THREE.Geometry();
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeFaceNormals();// computeFaceNormals 方法让Three.js 决定每个面的法向量,而法向量用于决定不同光源下的颜色
复制代码需要注意的是,创建面的顶点时的创建顺序,因为顶点顺序决定了某个面是面向还是背向摄像机。如果你想创建面向摄像机的面,那么顶点的顺序是顺时针的,反之顶点的顺序是逆时针的
- 材质 ( Material )。材质就像物体的皮肤,决定了几何体的外表。例如,材质可以定义一个几何体看起来是否像金属,是否是透明的等等。在 Three.js 中,材质对象有一些共同的属性,例如:常用的基础属性(控制物体的透明度、可见性、引用),融合属性(决定物体如何与背景融合)以及高级属性(控制底层 WebGL 上下文对象渲染物体的方式)。如下图所示,我们为大家整合了三类属性:

从对上面概念的阐述我们知道了创建一个网格模型,需要几何体、材质。当网格创建好之后,我们就可以将它添加到场景中并进行渲染。同样,我们可以对网格对象进行操作,网格对象有下列几种方法和属性:
- position: 决定网格对象相对于父对象的位置(通常父对象就是添加该对象的场景);
- rotation: 设置绕每个轴的旋转弧度;
- scale: 该属性可以沿着 x, y, z 轴缩放对象;
- translateX(amount): 沿着 x 轴将对象平移 amount 距离;
- translateY(amount): 沿着 y 轴将对象平移 amount 距离;
- translateZ(amount): 沿着 z 轴将对象平移 amount 距离;
- visible(amount): 决定网格对象的可见性。该属性值为 false 时, THREE.Mesh 将不会被渲染到场景中;
光源
Three.js 中的光源可以分为两种类型。我们用下图进行分解:

其中,基础光源是最常见的,所有这些光源都是基于 THREE.Light 对象扩展的。对于这些光源,我们需要知道的是:
- THREE.AmbientLight 光源的颜色可以附加到场景中的每一种颜色上,通常用来柔化生硬的颜色和阴影。
- THREE.PointLight 光源会朝所有方向发射光线,不能被用来阴影。
- THREE.SpotLight 光源类似手电筒,它有一个锥形的光束,可以配置它随着距离的增大而逐渐变弱,并且可以生成阴影。
- THREE.Directional 光源相当于远光的效果,比如太阳光。它的光线呈平行,其光强并不会随着与目标对象距离的增大而减弱。
- THREE.HemisphereLight 光源,该光源考虑了天空和地面的反射,可以具备更加自然的户外效果。
- THREE.AreaLight 不从单个点发射光线,而是从一个很大的区域发射光线。























![[桜井宁宁]COS和泉纱雾超可爱写真福利集-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/4d3cf227a85d7e79f5d6b4efb6bde3e8.jpg)

![[桜井宁宁] 爆乳奶牛少女cos写真-一一网](https://www.proyy.com/skycj/data/images/2020-12-13/d40483e126fcf567894e89c65eaca655.jpg)
