Three.js
的作用就是做3D效果,一说到3D就绕不过一个话题,那就是阴影。而要出现阴影的效果,那么就要涉及光源。本章介绍Three.js
中光源相关的知识。
光源简介
光源是THREE.Light类的子类。所有光源都有2个属性,一个是color
,是一个THREE.Color
类型的值,表示光源的颜色;另一个是intensity
,一个浮点型的值,表示光照强度。本章所有的光源都有这2个值,你可以在本章配套代码中随意修改这2个值。
这章我们围绕一个例子来展开,基本的代码如下:
1 | // 添加正方体 |
上面添加了一个正方形(BoxGeometry),一个球形(SphereGeometry),一个平地(PlaneGeometry)。这三个Geometry
你可能不熟悉,我们会在下个章节来专门讲,现在不熟悉无所谓,此时的效果如下:
SpotLight
SpotLight是一种圆锥形的光源(聚光灯光源),类似于手电筒或者路灯这样的光源,SpotLight具有方向,并且可以产生阴影。现在我们给上面的场景中添加阴影。要想让场景中有一下4个步骤:
1.添加光源并设置可以传播阴影:
1 | // 添加光源 |
Three.js
出于性能考虑,默认castShadow
是false
,也就是默认不会产生阴影的。
2.使用可以感光的材质。
我们上述使用的材质MeshNormalMaterial
是不会对光源有反应的材质,我们需要一种对光源产出反应的材质,常用的感光材质有:MeshLambertMaterial和MeshPhongMaterial。我们这里就使用MeshLambertMaterial
材质来替换上面的MeshNormalMaterial
吧,材质相关的知识将会在下下章节中讲。
1 | // ... 其他代码 |
这里需要注意的是,如果把材质换成感光材质而没有引入光源,是看不到物体的,跟我们在黑暗中看东西是一样的。
3.设置物体传播(产生)阴影或接收阴影:
1 | cube.castShadow = true; |
4.渲染器开启阴影映射:
1 | renderer.shadowMapEnabled = true; |
此时的效果如下:
PointLight
PointLight是点光源,听名字就知道了,它是一个点向四面八方发射光线的光源,点光源不能产生阴影。
我们在上一个例子中的添加一个点光源:
1 | var pointLight = new THREE.PointLight("#ffd200"); |
修改聚光灯光源的角度,运行后大概如下:
这里的阴影是上一个聚光灯光源产生的效果,可以使用下面代码把聚光灯光源去掉,那么就只有点光源的效果了。
1 | spotLight.visible = false; |
此时的效果大概如下:
这一块建议运行一下代码,代码中可以更好的测试各个参数。
DirectionalLight
DirectionalLight顾名思义是一种平行的直线光源(平行光光源)。平行光光源的光线是平行的,可以产生阴影,所有光的强度都一样。它有一个target
属性表示照射到哪个位置上,另外可以使用directionalLight.shadow.camera.left
或者directionalLight.shadowCameraLeft
来设置阴影的左边距,同样的也可以设置右边、上边、下边等边距,这样就可以确定一个阴影的范围(阴影越大性能会越差,所以平行光需要设置阴影范围)。
我们把第一个例子中的聚光灯光源换成平行光光源,如下:
1 | // 添加光源 |
此时的效果大概如下:
AmbientLight
AmbientLight的作用是给场景添加一种全局的颜色。该光源没有方向,也不产生阴影。如果你需要给场景中添加一种额外的统一的颜色,那么可以考虑使用AmbientLight
,比如在上一个例子中添加一种紫色来烘托氛围,那么就可以使用该光源。
1 | var ambientLight = new THREE.AmbientLight('#9370DB'); |
上述效果如下:
HemisphereLight
上述AmbientLight
主要的作用就是给环境中添加一种颜色,还有一种给环境中添加颜色的光源,就是HemisphereLight。HemisphereLight
是一种更加贴近自然的光源,它的第一个参数表示天空的颜色,第二个参数表示地面(或者环境)的颜色,第三个参数是intensity
表示强度。我们把上个例子中的AmbientLight
替换为HemisphereLight
,如下:
1 | var hemisphereLight = new THREE.HemisphereLight('#87ceeb', '#f5deb3', 0.4); |
上述效果如下: