• No results found

SpotLight – the light with a cone effect

A SpotLight is probably one of the lights that you'll use most often (especially if you want a shadow). A SpotLight is a light source that has a cone effect. You can compare this with a flashlight, or a lantern. This light has a direction

and an angle at which it produces light. The properties that we've seen for the PointLight source also apply to the SpotLight. A SpotLight source also has a number of additional properties:

Property Description

castShadow If set to true, this light will cast shadows.

shadowCameraNear From what point from the light the shadows should be created.

shadowCameraFar To what point from the light should the shadows be created.

shadowCameraFov How large is the field of view that is used to create the shadows (see the section on the perspective camera in

Chapter 2, Working with the Basic Components That Make Up a Three.js Scene.)

target Determines where the light is aimed.

shadowBias Can be used to offset the position of the rendered shadow.

angle How wide the beam is from this light source. It is measured in radians. Defaults to Math.PI/3.

exponent A light is aimed at a specific target. The farther away the light source is from this direction, the more the light's intensity will decrease. This value determines how fast the light's intensity decreases.

onlyShadow If set to true, this light will only cast a shadow and won't

add any light to the scene.

shadowCameraVisible If set to true, you can see how and where this light source

casts a shadow (see the example in the following section).

shadowDarkness Defaults to 0.5. Defines how dark the shadow is rendered. Can't be changed after the scene is rendered.

shadowMapWidth Determines how many pixels are used to create the shadow. It can be increased when the shadow has jagged edges or doesn't look smooth. Can't be changed after the scene is rendered.

shadowMapHeight Determines how many pixels are used to create the shadow. It can be increased when the shadow has jagged edges or doesn't look smooth. Can't be changed after the scene is rendered.

Working with the Different Light Sources Available in Three.js

[ 76 ]

Creating a SpotLight source is very easy. Just specify the color, set the properties you want, and add it to the scene as shown:

var pointColor = "#ffffff";

var spotLight = new THREE.SpotLight(pointColor); spotLight.position.set(-40, 60, -10);

spotLight.castShadow = true; spotLight.target = plane; scene.add(spotLight);

Not that different from the PointLight source. The only difference is that we will set the castShadow property to true because we want shadows, and we need to set the target for the SpotLight source. The target determines where the light is aimed at. In this case we will point it at the center of the ground plane. When you run the 03-spot-light.html example, you'll see a scene like the following screenshot:

Chapter 3

[ 77 ]

In this example you can set a number of SpotLight-specific properties. One of them

is the target property. If we set this property to the blue sphere, the light will stay aimed at the center of the sphere, even if it moves around the scene. When we created the light source, we aimed it at the ground plane, and in our example we can also aim it at the other two objects. But what if you don't want to aim the light

at a specific object, but at an arbitrary point in space? You can do that by creating an

empty THREE.Object3D() instance as follows:

var target = new THREE.Object3D();

target.position = new THREE.Vector3(5, 0, 0);

And set the target property of the SpotLight source as shown:

spotlight.target = target

In the table earlier in this section, we showed a couple of properties that can be used to control how the light emanates from the SpotLight source. The distance and angle properties define the shape of the cone. The angle property defines the width of the cone and, with the distance property, we can set the length of the cone. If we

dive into the Three.js source code, we can find exactly how this is defined:

var coneLength = light.distance ? light.distance : 10000; var coneWidth = coneLength * Math.tan( light.angle * 0.5 ) * 2;

Without diving too deep into trigonometry, let's have a quick look at the second statement. The tangent function (Math.tan()) can be used to determine the ratio of the opposite side (the cone width) to the length of the adjacent side (the cone length). The

following figure shows how the angle and cone length determine the cone width:

cone length

cone width

angle

In the Three.js code, the light source angle is first divided by two (see the earlier figure), since the tangent function should be used on right-angled triangles. To get

the cone width, the result from the Math.tan() function, the ratio, is multiplied by the cone length. This gives us half the cone width, which we will multiply by two to

Working with the Different Light Sources Available in Three.js

[ 78 ]

Usually you won't have to set these values, since they come with reasonable defaults, but you can use these properties, for instance, to create SpotLight sources that have a very narrow beam, or quickly decrease in light intensity. The last property that you can use to change the way a SpotLight light is perceived is the exponent property. With this property, you can set how fast the light intensity will decrease from the center of the light cone, as shown in the following screenshot:

We've got a very bright light (high intensity) that rapidly decreases in intensity (high exponent) as it moves away from the center. We could also have created the same focused beam effect by using a small exponent value, and a small angle.

A very small angle can quickly lead to artifacts (this is a term used in graphics for unwanted distortions and strangely-rendered parts of the screen) in the way that the light is rendered.

Chapter 3

[ 79 ]

Before moving on to the next light, we'll quickly look at the shadow-related properties that are available to the SpotLight source. We've already learned that we can get shadows by setting the castShadow property of the SpotLight source to true. The Three.js library also allows you very fine-grained control on how the

shadow is rendered. This is done by a couple of properties that we explained in the table earlier in this section. With the shadowCameraNear, shadowCameraFar, and shadowCameraFov properties, you can control how and where this light will cast a

shadow. This works in the same way as the perspective camera field of view that we

explained in the previous chapter. The easiest way to see this in action is by setting the shadowCameraVisible property to true; you can do this by checking the menu's

debug checkbox. This shows the area that is used to determine the shadows for this light, as you can see in the following screenshot:

Working with the Different Light Sources Available in Three.js

[ 80 ]

I'll end this section with a couple of pointers should you run into issues with shadows:

• Enable the shadowCameraVisible property. This shows the area that is affected by this light for shadow purposes.

• If the shadow looks blocky, you can either increase the shadowMapWidth and shadowMapHeight properties, or make sure that the area that is used to calculate the shadow tightly wraps your object. You can use the shadowCameraNear, shadowCameraFar, and shadowCameraFov properties to

configure this area.

• Remember that you not only have to tell the light to cast shadows, you also have to tell each geometry whether it will receive and/or cast shadows, by setting the castShadow and receiveShadow properties.

DirectionalLight – for a far away sun-like light