当前位置: > > > Three.js - 光源使用详解2(聚光灯 SpotLight、平行光 DirectionLight)

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 属性来告诉几何体对象是否接收或投射阴影。
//平面接收阴影
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。如果将这个属性设置为 trueThree.js 会使用一个替代方法来生成阴影。它将阴影的生成分裂为由 shadowCascadeCount 指定的值。这将导致靠近摄相机视点会产生更具细节的阴影,而远离摄像机视点阴影的细节更少。
  • 要使用这个选项需要尝试设置一下属性:shadowCascadeCountshadowCascadeBiasshadowCascadeWidthshadowCascadeHeightshadowCascadeNearZ shadowCascadeFarZ 属性。
评论0