学习之前
示例演示
参考资料
api查询:http://www.webgl3d.cn/threejs/docs/index.html#
代码地址:https://github.com/mrdoob/three.js/
学习方法讲解
对于没有基础的前端小伙伴,最好的学习方法,
1.先理清楚知识主干,对于枝叶我们先了解一些常用的,千万不要求全,这样会打击大家学习的兴趣。
2.结合案例学习,这样可以增强我们的学习兴趣,就像做化学实验一样,不要仅仅阅读文字
3.在实践中学习,比如后面我们工作中用到threejs,这时候我们用到哪种效果,我们就去查相似的demo,然后通过查询api文档,有的放矢的学习
课程的安排:
首先整体讲解一下threejs,让我们对threejs有一个整体的了解,也就是抓住主干知识
然后对每个主干知识进行稍稍讲解,够用
最后带着大家完成我们实战案例(vr看房)
整体介绍
Three.js是基于原生WebGL封装运行的三维引擎(js与jq的关系),在所有WebGL引擎中,Three.js是国内使用最广泛的三维引擎。可以用来开发Web3D应用 。
前两年非常火的小游戏跳一跳就是使用Three.js引擎开发的。开发3D类的H5小游戏或者微信小游戏,Three.js引擎是非常好的选择。
从实际生活中拍照角度理解
立方体网格模型和光照组成了一个虚拟的三维场景,相机对象就像你生活中使用的相机一样可以拍照,只不过一个是拍摄真实的景物,一个是拍摄虚拟的景物,拍摄一个物体的时候相机的位置和角度需要设置,虚拟的相机还需要设置投影方式,当你创建好一个三维场景,相机也设置好,就差一个动作“咔”,通过渲染器就可以执行拍照动作。
写一个helloworld
- // 1.创建场景对象Scene
- var scene = new THREE.Scene();
-
- // 2.创建几何体
- // var geometry = new THREE.SphereGeometry(60, 40, 40); //创建一个球体几何对象
- var geometry = new THREE.BoxGeometry(100, 100, 100); //创建一个立方体几何对象Geometry
-
- // 3.创建材质
- var material = new THREE.MeshLambertMaterial({
- color: 0x0000ff
- });
-
- // 4.创建网格模型
- var mesh = new THREE.Mesh(geometry, material); //网格模型对象Mesh
- scene.add(mesh); //网格模型添加到场景中
-
- // 5.设置光源
- //点光源
- var point = new THREE.PointLight(0xffffff);
- point.position.set(400, 200, 300); //点光源位置
- scene.add(point); //点光源添加到场景中
- //环境光
- var ambient = new THREE.AmbientLight(0x444444);
- scene.add(ambient);
-
- // 6.创建相机对象
- var width = window.innerWidth; //窗口宽度
- var height = window.innerHeight; //窗口高度
- var k = width / height; //窗口宽高比
- var s = 200; //三维场景显示范围控制系数,系数越大,显示的范围越大
- var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
- camera.position.set(200, 300, 200); //设置相机位置
- camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
-
- //7.创建渲染器对象
- var renderer = new THREE.WebGLRenderer();
- renderer.setSize(width, height);//设置渲染区域尺寸
- renderer.setClearColor(0xb9d3ff, 1); //设置背景颜色
- document.body.appendChild(renderer.domElement); //body元素中插入canvas对象
-
- //8.执行渲染操作 指定场景、相机作为参数
- renderer.render(scene, camera);
不能鼠标移动太难受,加一个Orbitcontrol让鼠标可以交互
场景
场景其实可以理解成一个容器,他里面包括:各种人物物体(模型)和灯光
创建一个场景
var scene = new THREE.Scene();
将其他实体添加到场景的方法
add
几何体
对于初学者,这个几何体我们可以简单的理解为数学里的几何体就可以了。
我们首先来了解一下,threejs中提供了哪些几何体
接下来我们在前面完整demo里,测试一下两个几何体:长方体和球体 打开api文档看一下这两个几何体的api介绍
几何体的本质:
对于球体:SphereGeometry(radius, widthSegments, heightSegments) 第一个参数radius约束的是球的大小,参数widthSegments、heightSegments约束的是球面的精度,球体你可以理解为正多面体,就像圆一样是正多边形,当分割的边足够多的时候,正多边形就会无限接近于圆,球体同样的的道理。
一个立方体网格模型,有6个面,每个面至少两个三角形拼成一个矩形平面,每个三角形三个顶点构成,对于球体网格模型而言,同样是通过三角形拼出来一个球面,三角形数量越多,网格模型表面越接近于球形
材质
所谓材质,简单地说就是字面意思,就像生活中你聊天一样,说这是塑料材质,这是金属材质,这是纤维材质...,
为了模拟现实生活中的这些材质,threejs提供了大量的材质类,下面我们整体了解一下有哪些材质类。有个了解即可,需要的时候在用api文档查阅。
看看常用的属性
所有子类的材质都会从父类材质Material继承透明度opacity、面side等属性,这些来自父类的属性都是子类共有的属性。
相机
理解Threejs相机对象的最简单的方式就是参考生活中真实的相机拍照过程。
生活中的物体都是三维的,但是人的眼睛只能看到正面,不能看到被遮挡的背面,三维几何体在人眼睛中的效果就像一张相机拍摄的二维照片,你看到的是一个2D的投影图。 空间几何体转化为一个二维图的过程就是投影,不同的投影方式意味着投影尺寸不同。
对于正投影而言,一条直线放置的角度不同,投影在投影面上面的长短不同;
对于透视投影而言,投影的结果除了与几何体的角度有关,还和距离相关, 人的眼睛观察世界就是透视投影,比如你观察一条铁路距离越远你会感到两条轨道之间的宽度越小。
Threejs常用的相机对象就是正投影相机OrthographicCamera和透视投影相机PerspectiveCamera
三维场景中坐标值不在三维空间中的网格模型不会被渲染出来,会被剪裁掉,比如你把上面代码中far参数的值从1000更改为420,你会发现长方体的一部分无法显示。
可视区域:类比人的眼睛,是不是也有一定的可以区域。
人的眼睛按正常视力的话,站在平地上,眼睛看的距离大约有500米,对500米之外的景物,形象比较模糊
了解了相机初始化后,我们需要知道怎么配置一个相机
模型
从Three.js角度来说,Threejs模型对象就是由Threejs几何体Geometry和Threejs材质Material构成,材质主要设置三维模型的颜色等外观样式,几何体主要是通过顶点坐标数据表达三维模型的外形形状。
点模型Points、线模型Line、网格网格模型Mesh都是由几何体Geometry和材质Material构成,这三种模型的区别在于对几何体顶点数据的渲染方式不同
光源
Threejs虚拟光源是对自然界光照的模拟,threejs搭建虚拟场景的时候,为了更好的渲染场景,往往需要设置不同的光源,设置不同的光照强度,就像摄影师给你拍照要设置各种辅助灯光一样。下图这些设备我们应该是见过吧,我们可以直接把三维场景中的光源理解成这里的灯光设备
接下来,我们调整一下,环境光,点光源,平行光,聚光灯光源,看看效果
- //环境光:环境光颜色RGB成分分别和物体材质颜色RGB成分分别相乘
- var ambient = new THREE.AmbientLight(0x444444);
- scene.add(ambient);//环境光对象添加到scene场景中
-
- //点光源
- var point = new THREE.PointLight(0xffffff);
- //设置点光源位置,改变光源的位置
- point.position.set(400, 200, 300);
- scene.add(point);
-
-
- // 平行光
- var directionalLight = new THREE.DirectionalLight(0xffffff, 1);
- // 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
- directionalLight.position.set(80, 100, 50);
- // 方向光指向对象网格模型mesh2,可以不设置,默认的位置是0,0,0
- directionalLight.target = mesh2;
- scene.add(directionalLight);
-
-
- // 聚光光源
- var spotLight = new THREE.SpotLight(0xffffff);
- // 设置聚光光源位置
- spotLight.position.set(200, 200, 200);
- // 聚光灯光源指向网格模型mesh2
- spotLight.target = mesh2;
- // 设置聚光光源发散角度
- spotLight.angle = Math.PI / 6
- scene.add(spotLight);//光对象添加到scene场景中
精灵模型
创建精灵模型对象Sprite和创建网格模型对象一样需要创建一个材质对象,不同的地方在于创建精灵模型对象不需要创建几何体对象Geometry,精灵模型对象本质上你可以理解为已经内部封装了一个平面矩形几何体PlaneGeometry,矩形精灵模型与矩形网格模型的区别在于精灵模型的矩形平面会始终平行于Canvas画布。
用途
说到精灵模型对象,这种情况下你肯定关心它的用途,关于用途,你可以在三维场景中把精灵模型作为一个模型的标签,标签上可以显示一个写模型的信息,你可以通过足够多的精灵模型对象,构建一个粒子系统,来模拟一个下雨、森林、或下雪的场景效果。实现广告牌。
测试一下效果
纹理贴图
纹理贴图是Threejs一个很重要的内容,游戏、产品展示、物联网3D可视化等项目,都需要加载模型的同时需要处理纹理贴图。
漫游案例: