全网最简易Three.js入门教程——基本概念及进阶路径推荐

493 阅读5分钟

最近群里的人都在卷 Three.js,出于好奇心、好胜心及功利心的驱使,本人简单地翻阅了一下相关资料,对 Three.js 进行了一番浅尝辄止的学习,可以说是浅浅地入了一下门,在这里对这几天的学习成果做个简单总结,希望对大家能够有所帮助。

首先附上这几天学习用到的材料:

  1. 官方文档
  2. 一个不错的中文教程
  3. Three.js开发指南

Three.js 是什么?

个人理解,Three.js 就是一个 JavaScript 3D 渲染引擎,通过它提供的 API 可以非常方便地在网页上构建及渲染 3D 模型,Three.js 提供了多种渲染器(什么是渲染器后面会介绍),如 WebGLRenderer、CSS3DRenderer、SVGRenderer 等,最常用的当然是 WebGLRenderer,WebGLRenderer 会调用 WebGL 渲染引擎来渲染模型,而 WebGL 有显卡加速的加成,嗯,很厉害的样子。

Three.js 中必知必会的几个概念

在开始写 Three.js 代码之前,有几个概念必须要先了解一下,了解了这几个概念之后,所有的 Three.js 的代码都很好理解了,都是一样的套路、一样的模式。

  1. 场景 Scene:场景就像是舞台,是 Three.js 中一切物体存在的空间,你的模型中的一切物体都必须先添加到场景中才能渲染出来
  2. 相机 Camera:现实生活中,我们观察一个物品的时候,可以从四面八方任意一个角度去观察它,但是对于具体的某一个时刻来说,我们只能从某一个具体的角度去观察它,只能观察到该物品的某一个面,相机就代表了这样一个视角,相机的位置和角度等参数决定了我们的3D模型在浏览器上展现的样子,模型是3D的,但是最终渲染的结果只能是一面
  3. 渲染器 Renderer:渲染器负责最终的渲染,将相机“看到的”影像展现在浏览器上
  4. 模型对象:也就是你要展示的3D对象,包括点模型 Points、线模型 Line、网格模型 Mesh、精灵模型 Sprite 这几种,模型由几何体 Geometry 和材质 Material 两部分组成,几何体描述了模型的形状,材质描述了模型的外观,有点像 HTML 和 CSS 的关系
  5. 光源 Light:光源模拟的是生活中的光照效果,使得3D模型更真实,通过光源可以产生阴影效果,和生活中的光源一样,Three.js 中的光源也分为点光源、平行光源、聚光灯光源等

一句话总结一下就是:通过场景搭建平台,通过模型对象的组合构建内容,相机截取视图,渲染器最终将图像展现到浏览器上。

好了,了解了这几个概念之后,就可以进行简单的3D模型的构建了。

一个简单的例子

下面这个例子来自于 《Three.js开发指南》,做了适当的精简,最终效果图如下:

image.png

首先要引入 three.js

<script type="text/javascript" src="../libs/three.js"></script>

在 body 中预置一个 div 元素用来存放最终渲染出来的结果

<div id="WebGL-output"></div>

然后,场景、相机、渲染器三件套来一套

var scene = new THREE.Scene();

var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);

var renderer = new THREE.WebGLRenderer();

设置渲染器相关属性

// 设置背景色
renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
// 设置渲染尺寸
renderer.setSize(window.innerWidth, window.innerHeight);
// 开启渲染阴影效果
renderer.shadowMapEnabled = true;

创建地面网格模型

// 这里的细节不用在意,总之就是创建平面几何体,然后选择一个材质,然后创建一个网格模型
var planeGeometry = new THREE.PlaneGeometry(40, 20);
var planeMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
var plane = new THREE.Mesh(planeGeometry, planeMaterial);
// 接收来自其他物体的投影,不理解也没关系,不要在意这些细节……
plane.receiveShadow = true;

设置地面的旋转角度及位置

plane.rotation.x = -0.5 * Math.PI;
plane.position.x = 0;
plane.position.y = 0;
plane.position.z = 0;

将地面网格对象添加到场景中

scene.add(plane);

同上,创建立方体网格模型,并设置相关属性

var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);
var cubeMaterial = new THREE.MeshLambertMaterial({color: 0xff0000});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
// 设置立方体网格模型产生投影,与上面地面网格模型的 receiveShadow 属性相配合
cube.castShadow = true;

// 设置立方体的位置
cube.position.x = -4;
cube.position.y = 3;
cube.position.z = 0;

// 将立方体添加到场景中
scene.add(cube);

设置相机的位置及视角

camera.position.x = -30;
camera.position.y = 40;
camera.position.z = 30;
// 相机朝向场景的中心
camera.lookAt(scene.position);

添加光源,并设置光源的位置

var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(-40, 60, -10);
// 要产生投影,光源本身也要设置 castShadow 等于 true
spotLight.castShadow = true;

同样的,光源也要添加到场景中

scene.add(spotLight);

设置渲染器渲染的结果输出到 WebGL-output div 上

document.getElementById("WebGL-output").appendChild(renderer.domElement);

调用渲染器的渲染方法,开始渲染模型

renderer.render(scene, camera);

进阶路径推荐

了解了上面几个基本概念之后,可以说是打通了任督二脉,理解上面的这个例子基本没什么难点,最多也就是查查 API,这也正是 Three.js 的厉害之处。

但是,以目前的知识,我们还做不到可以得心应手地实现所有需求,这个时候应该结合例子去学习,当然还是推荐由浅入深学习,在例子中一点一点找感觉,推荐的学习路径如下:

  1. 《Three.js开发指南》 打基础不错,对 Three.js 有系统的讲解,包括纹理、动画、着色器、物理效果、声音等
  2. 官网例子
  3. 网友实现的酷炫实例

听说更深入的学习就要学习 WebGL 相关的知识了,还有图形学等,当然,那是更高级的阶段了,现阶段也不需要关心。

怎么样,是不是有点感觉了?心动了就去折腾吧! Three.js 大师在向你招手。