Three.js - 光源使用详解2(聚光灯 SpotLight、平行光 DirectionLight)
三、THREE.SpotLight(聚光灯光源)
1,基本介绍
- THREE.SpotLight 是一种具有锥形效果的光源,该光源拥有产生光的方向和角度。我们可以将其与手电筒或者灯笼产生的光进行对比。
- THREE.SpotLight 是最常使用的光源之一,特别是如果我们想要使用阴影的话。
2,属性介绍
- angle:角度。即光源发射出的光束的宽度。单位是弧度,默认值:Math.PI/3
- castShadow:投影。如果设置为 true,这个光源就会生成阴影。
- color:光源颜色。
- distance:光源照射的距离。默认值为 0,这意味着光线强度不会随着距离增加而减弱。
- exponent:光强衰减指数。使用 THREE.SpotLight 光源,发射的光线的强度随着光源距离的增加而减弱。exponent 属性决定了光线强度递减的速度。使用低值,从光源发出的光线将到达远处的物体,而使用高值,光线仅能到达非常接近 THREE.SpotLight 光源的物体。
- intensity:光源照射的强度。默认值:1
- onlyShadow:仅阴影。如果此属性设置为 true,则该光源只生成阴影,而不会在场景中添加任何光照。
- position:光源在场景中的位置
- shadow.bias:用来偏置阴影的位置。当你使用非常薄的对象时,可以使用它来解决一些奇怪的效果。如果你看到奇怪的阴影效果,将该属性设置为很小的值(例如 0.01)通常可以解决问题。此属性的默认值为 0。
- shadow.camera.far:投影远点。表示到距离光源的哪一个位置可以生成阴影。默认值:5000
- shadow.camera.fov:投影视场。表示用于生成阴影的视场有多大。默认值:50
- shadow.camera.near:投影近点。表示距离光源的哪一个位置开始生成阴影。默认值为 50
- shadow.map.width 和 shadow.map.height:阴影映射宽度和阴影映射高度。决定了有多少像素用来生成阴影。当阴影具有锯齿状边缘或看起来不光滑时,可以增加这个值。在场景渲染之后无法更改。两者的默认值均为:512
- target:目标。使用 THREE.SpotLight 光源时,它的指向很重要。使用 target 属性,你可以将 THREE.SpotLight 光源指向场景中的特定对象或位置。注意,此属性需要一个 THREE.Object3D 对象(如 THREE.Mesh)。
- visible:是否可见。如果该属性设置为 true(默认值),该光源就会打开。如果设置 false,光源就会关闭。
3,基本用法
(1)创建聚光灯光源非常简单,只要指定颜色(并设置相关属性),然后添加到场景中即可。要特别注意如下几个属性:
- castShadow:如果想要阴影,该属性要设置为 true。
- target:该属性决定光源照射的位置。这里我们将其指向 plane 对象(地板)。
var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(30, 25, -2); spotLight.castShadow = true; spotLight.target = plane; scene.add(spotLight);
(2)如果我们不想将 target 瞄准一个特定的对象,而是空间中的任意一点。可以通过创建一个 THREE.Object3D() 对象来实现。
//创建一个3d对象作为聚光灯的目标 var target = new THREE.Object3D(); target.position.set(30, 0, 0); scene.add(target); //创建聚光灯 var spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(30, 25, -2); spotLight.castShadow = true; spotLight.target = target; scene.add(spotLight);
4,阴影相关用法
(1)除了告诉光源要生成阴影外,还必须通过配置每个几何体的 castShadow 和 receiveShadow 属性来告诉几何体对象是否接收或投射阴影。
(3)如果想要阴影更加柔和,可以在 THREE.WebGLRenderer 对象上设置不同的 shadowMap.type 属性值:
//平面接收阴影 plane.receiveShadow = true; //方块和球体投射阴影 cube.castShadow = true; sphere.castShadow = true;
(2)配合使用 THREE.CameraHelper,我们可以把用来决定阴影的光照区域显示出来,方便调试。
var helper = new THREE.CameraHelper(spotLight.shadow.camera ); scene.add(helper);
(3)如果想要阴影更加柔和,可以在 THREE.WebGLRenderer 对象上设置不同的 shadowMap.type 属性值:
- THREE.PCFShadowMap:默认阴影
- THREE.PCFSoftShadowMap:更加柔和的阴影
var renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0xEEEEEE)); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap;
四、THREE.DirectionLight(平行光)
1,基本介绍
- THREE.DirectionLight 可以看作是距离很远的光,它发出的所有光线都是相互平行的。平行光的一个范例就是太阳光。
- 平行光不像上面的聚光灯(通过 distance 和 exponent 属性来微调)那样离目标越远越暗淡。被平行光照亮的整个区域接受到的光强是一样的。
2,属性介绍
- position:光源在场景中的位置。
- target:目标。使用 THREE.DirectionLight 光源时,它的指向很重要。使用 target 属性,你可以将 THREE.SpotLight 光源指向场景中的特定对象或位置。注意,此属性需要一个 THREE.Object3D 对象(如 THREE.Mesh)。
- intensity:光源照射的强度。默认值:1
- castShadow:投影。如果设置为 true,这个光源就会生成阴影
- onlyShadow:仅阴影。如果此属性设置为 true,则该光源只生成阴影,而不会在场景中添加任何光照。
- shadow.camera.near:投影近点。表示距离光源的哪一个位置开始生成阴影。
- shadow.camera.far:投影远点。表示到距离光源的哪一个位置可以生成阴影。
- shadow.camera.left:投影左边界。
- shadow.camera.right:投影右边界。
- shadow.camera.top:投影上边界。
- shadow.camera.bottom:投影下边界。
- shadow.map.width 和 shadow.map.height:阴影映射宽度和阴影映射高度。决定了有多少像素用来生成阴影。当阴影具有锯齿状边缘或看起来不光滑时,可以增加这个值。在场景渲染之后无法更改。两者的默认值均为:512
3,基本用法
(1)对于 THREE.DirectionLight 来说,由于所有的光线都是平行的,所以不会有光锥,而是一个立方体区域。下面代码我们配合 THREE.CameraHelper 对象,将用来决定阴影的光照区域显示出来,方便调试。
//创建平行光 var directionalLight = new THREE.DirectionalLight(0xffffff); directionalLight.position.set(25, 17, -2); directionalLight.castShadow = true; directionalLight.target = plane directionalLight.shadow.camera.near = 2; directionalLight.shadow.camera.far = 40; directionalLight.shadow.camera.left = -20; directionalLight.shadow.camera.right = 20; directionalLight.shadow.camera.top = 20; directionalLight.shadow.camera.bottom = -20; scene.add(directionalLight); //显示光照区域 var helper = new THREE.CameraHelper(directionalLight.shadow.camera ); scene.add(helper);
(2)有时我们不想将 target 瞄准一个特定的对象,而是空间中的任意一点。可以通过创建一个 THREE.Object3D() 对象来实现。
//创建一个3d对象作为平行光的目标 var target = new THREE.Object3D(); target.position.set(8, 0, 5); scene.add(target); //创建平行光 var directionalLight = new THREE.DirectionalLight(0xffffff); directionalLight.position.set(25, 17, -2); directionalLight.castShadow = true; directionalLight.target = target directionalLight.shadow.camera.near = 2; directionalLight.shadow.camera.far = 40; directionalLight.shadow.camera.left = -20; directionalLight.shadow.camera.right = 20; directionalLight.shadow.camera.top = 20; directionalLight.shadow.camera.bottom = -20; scene.add(directionalLight);
3,shadowCascade 属性介绍
- THREE.DirectionLight 还有一个特有的属性:shadowCascade。当我们需要使用 THREE.DirectionLight 在一个很大的区域设置阴影时,这个属性可以帮助创建更好的阴影效果。
- 该属性默认为 false。如果将这个属性设置为 true,Three.js 会使用一个替代方法来生成阴影。它将阴影的生成分裂为由 shadowCascadeCount 指定的值。这将导致靠近摄相机视点会产生更具细节的阴影,而远离摄像机视点阴影的细节更少。
- 要使用这个选项需要尝试设置一下属性:shadowCascadeCount、shadowCascadeBias、shadowCascadeWidth、shadowCascadeHeight、shadowCascadeNearZ 和 shadowCascadeFarZ 属性。