最近群里的人都在卷 Three.js,出于好奇心、好胜心及功利心的驱使,本人简单地翻阅了一下相关资料,对 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 的代码都很好理解了,都是一样的套路、一样的模式。
- 场景 Scene:场景就像是舞台,是 Three.js 中一切物体存在的空间,你的模型中的一切物体都必须先添加到场景中才能渲染出来
- 相机 Camera:现实生活中,我们观察一个物品的时候,可以从四面八方任意一个角度去观察它,但是对于具体的某一个时刻来说,我们只能从某一个具体的角度去观察它,只能观察到该物品的某一个面,相机就代表了这样一个视角,相机的位置和角度等参数决定了我们的3D模型在浏览器上展现的样子,模型是3D的,但是最终渲染的结果只能是一面
- 渲染器 Renderer:渲染器负责最终的渲染,将相机“看到的”影像展现在浏览器上
- 模型对象:也就是你要展示的3D对象,包括点模型 Points、线模型 Line、网格模型 Mesh、精灵模型 Sprite 这几种,模型由几何体 Geometry 和材质 Material 两部分组成,几何体描述了模型的形状,材质描述了模型的外观,有点像 HTML 和 CSS 的关系
- 光源 Light:光源模拟的是生活中的光照效果,使得3D模型更真实,通过光源可以产生阴影效果,和生活中的光源一样,Three.js 中的光源也分为点光源、平行光源、聚光灯光源等
一句话总结一下就是:通过场景搭建平台,通过模型对象的组合构建内容,相机截取视图,渲染器最终将图像展现到浏览器上。
好了,了解了这几个概念之后,就可以进行简单的3D模型的构建了。
一个简单的例子
下面这个例子来自于 《Three.js开发指南》,做了适当的精简,最终效果图如下:
首先要引入 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 的厉害之处。
但是,以目前的知识,我们还做不到可以得心应手地实现所有需求,这个时候应该结合例子去学习,当然还是推荐由浅入深学习,在例子中一点一点找感觉,推荐的学习路径如下:
- 《Three.js开发指南》 打基础不错,对 Three.js 有系统的讲解,包括纹理、动画、着色器、物理效果、声音等
- 官网例子
- 网友实现的酷炫实例
听说更深入的学习就要学习 WebGL 相关的知识了,还有图形学等,当然,那是更高级的阶段了,现阶段也不需要关心。
怎么样,是不是有点感觉了?心动了就去折腾吧! Three.js 大师在向你招手。