总结以前的开发经验可以发现,再复杂的项目都是有着必不可少的骨架,所做的工作都是往骨架中去添加更多的内容。
在除去一切可以去除的内容之后,三维动画可以用一个球体来描述。
从零画一个球体
1、引入three.js
书中第一章用了不少篇幅写环境搭建,实际上有前端基础的同学都可以略过这部分。
如果选择webpack模块化的方法引入的话,在引用书中提到的几个辅助工具的时候会有些麻烦
(我因为这个浪费了几个小时🤯)
建议初期可以先直接使用案例代码学习
2、分析实例代码
书中提供了一些代码实例,拿最简单的01-02.js 来做分析
https://github.com/hiwords/learning-threejs-third/blob/master/src/chapter-01/js/01-02.js
实例代码中创建了四个物体:坐标轴、平面、立方体、球体
我们可以去掉不必要代码,直接分析如何创建球体
1、如何创建球体
// 定义物体的几何结构
var sphereGeometry = new THREE.SphereGeometry(30, 10, 10);
// 定义物体的材质
var sphereMaterial = new THREE.MeshBasicMaterial({
color: 0x7777FF,
wireframe: true
});
// 用刚才定义的几何结构和材质来创建物体
var sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);
// 定位球体中心的位置
sphere.position.set(0, 0, 0);
// 把球体添加到场景中
scene.add(sphere);
综上总结创建物体必须要:
- 定义几何结构
- 定义材质
- 根据结构和材质创建物体
- 确定物体在场景中的位置
- 把物体添加进场景中
2、如何创建三维场景
// 创建场景,所有三维物体的内容都是放在场景中的
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(0x000000)); // 设置场景背景色
renderer.setSize(window.innerWidth, window.innerHeight); // 设置尺寸
// 定义相机的位置和能够看到的内容(scene)
camera.position.set(30, 40, 80);
camera.lookAt(scene.position);
// 渲染场景和相机
renderer.render(scene, camera)
综上总结三维场景必定包含:
场景:scene是一定要new一个的
相机:就相当于我们看三维图像世界的眼睛
渲染器:可以理解为绘制场景极其内容的
还有一句代码:
document.getElementById("webgl-output").appendChild(renderer.domElement);
复制代码重点是这个render.domElement,它应该就是three.js封装的创建一个WebGL上下文的方法,返回的是一个canvas的Element object
丰富场景和物体内容
改变材质
因为不是每一种材质(Material)都会对光源有反应,所以我们先换一个对光源会产生反应的材质。
// MeshBasicMaterial 换成 MeshLambertMaterial
new THREE.MeshLambertMaterial({color: 0x7777FF});
更改完成后会发现页面变成了一片漆黑,这时候实际上是有渲染球体的,只是当前是黑色和背景色区分不开
为什么球体材质颜色明明是0x7777FF,但是却显示的漆黑的呢?
因为场景中没有光源,所以就相当于整个场景处于伸手不见五指的夜晚……黑漆漆
添加光源
“这个世界要有光!”
光源也可以理解为和球体同样级别的一个物体,所以添加光源要有这三步:
- 定义光源的属性
- 设置光源的位置
- 把光源添加到场景里
var spotLight = new THREE.SpotLight(0xFFFFFF)
spotLight.position.set(60, 70, 20);
scene.add(spotLight)
这样球体就可以被我们给看到了
但是整个场景还是有些暗
还有个环境光:AmbientLight,环境光的添加非常的简单
var ambienLight = new THREE.AmbientLight(0x555555); scene.add(ambienLight);
有了光就应该有影子
在我们的世界光和阴影总是会同时存在。可以这样理解:球被光照射,产生影子,投射在了地面上
我们要设置:
- 球可以产生影子:sphere.castShadow = true
- 地面可以承载影子: 类似创建球体一样创建一个平面plane
设置承载影子的属性plane.receiveShadow = true; - 光源要是能产生影子的光源: spotLight.castShadow = true
- 渲染器要允许渲染影子:render.shadowMap.enabled = true, 因为渲染阴影会耗费大量的计算资源,所以Three.js 默认是不会渲染阴影的,需要主动设置
注意:three.js开发指南第三版中 说到renderer.shadowMap.Enabled = true; 这里是会导致阴影无法出现的。正确的应该是 renderer.shadowMap.enabled = true
动起来
简单的动画无非就是requestAnimationFrame(渲染函数render)
var step = 0.1;
var n = 0
function render() {
n += step
sphere.position.set(0, -40, n)
console.log(n)
requestAnimationFrame(render)
renderer.render(scene, camera);
}
最最简单的就是这样平移改变球体位置的一个动画,更丰富的动画放在后面在了解吧,继续学习下一章的内容去了~
总结
- 不管是几何体还是摄像机还是光源,都是可以理解为一个物体。在创建的时候首先设定其属性,然后选择(设置)在场景中的位置xx.position.set(x,y,z)。最后添加进场景中scene.add(xx),一定要记得add进来,不然就不会显示
- 对光源能够产生反应的材质,场景中一定要加光源,如果没有光源,这种材质的几何都会呈现黑色
-
设置阴影需要:
- 让渲染器允许渲染阴影效果:renderer.shadowMap.enabled = true;
- 光源要是能够产生影子的spotLight.castShadow = true;
- 要有产生阴影和接收阴影的物体:xx.castShadow = true/xx.receiveShadow = true
- 生成一个简单的三维世界必须要创建的:创建场景、创建渲染器、创建几何体、创建相机
友情提示:three.js里面坐标系是右手定则的,可以理解为:拇指为Z,手掌为Y,四指为X
Y
↑
。----→ X
↙
Z
上面这个就是坐标系
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。