There are lights, and there is having a camera, and then there is having some action or movement in a scene. In this post will will be covering all three of those things in three.js, but with an emphases on spotlights. Spotlights as the name suggests is a directional light that will concentrate light in a cone like shape at a given target. This kind of light source differs from other options that will just brighten things up in general such as with ambient light, or give a cylinder like beam of light that where all rays move in a single parallel direction such as the case with directional light. So then in addition to adding directional or ambient light to a project, spotlights can be used as an additional kind of light source that can be moved around and focus light in on a specific area.
In this post I will not be covering materials in three.js in detail, but I also assume that you know that in three.js some materials respond to a light source, and others do not.
The last time I edited this post I was using three.js 0.127.0 ( or just simply r127 ) that came out in March of 2021, and when I first wrote this post I was using three.js 0.91.0 released in March of 2018.
When starting out with a basic example of a spotlight in three.js, at a very minimum I would want to create an instance of a spotlight by calling the THREE.SpotLight constructor with the new keyword, and then save that instance to a variable. Once I have my instance I would want to change its position using the Object3D position.set method to a point far away from the origin, or position it wherever I want it to be. I will then want to also make sure that the spotlight is facing the object that i want to shine light on.
Assuming that I have a mesh of some kind at the origin of my scene that is equipped with a material that responds to light such as the Lambert material, I should have a basic working example of reflectance going on. I will also need the usual scene, renderer, and camera all set up to make this an actual function demo.
By default a spotlight will point at the origin (0,0,0), because the mesh I am using in this demo is located at the origin, and I am not moving anything around, this works just okay with the default settings when it comes to things like the angle of the cone, and the light intensity. However if I want to change the target point that the spotlight is pointing at, and tweak some additional values, there is a great deal more to know about spotlights. Also there is more to know about materials as well, after all a material is what will respond to a light source. There is also a helper class that can be used to get a sense of what is going on with the spotlight by showing some lines that indicate it’s present status with respect to it’s position, angle, and what it is pointing at. In addition there is what to do in order to get shadows working if interested, so lets get to it.
The target property of the spotlight is what is of interest if you want to change what it is that the spotlight is pointing at. This can be something like an instance of Object3D, or a mesh in the scene. If you just want to change the target position of the spotlight, you will still want to add it’s target to the scene when you create the spotlight. If you do not at least do that then any change to the spotlights target position will not take effect.
It is also possible to set the target of the spotlight to a mesh that you have in the scene before hand.
Spotlights are a type of light in three.js that can be used to cast shadows. This is something that will not just work right out of the gate, as properties need to be set for the spotLight, renderer, and the objects in your scene that will cast, and receive shadows. Also shadows will not work with some renderer’s, but It should in most cases work just fine with the webGL renderer.
One thing to keep in mind though is that shadows will of course eat up more processing power compared to not using them, which is why you might consider putting in an option to turn them off when designing your project.
First off make sure you are using a renderer that supports shadows in the first place, the plane old 2d canvas renderer for instance does not. If you are using a renderer that does support shadows, and think you might do okay with the default settings for the shadow map of the renderer then all you have to do, for the renderer at least, is to set the shadowMap.enabled boolean to true.
The Object3D class has castShadow, and receiveShadow properties that both default to false. You will want to set one, the other, or both of these booleans to true for any and all objects in your scene that you want to have cast or receive shadows.
Notice that I am also using the Lambert material with my cube that will respond to light, be sure you are using a material like that unless for some reason you want an object that will cast a shadow, but not reflect a light source.
Just like the objects that will case or receive shadows, you will want to set the castShadow boolean of the spotLight instance to true. In addition there are some more properties of the spotLight that you may want to play with that have to do with setting the resolution of the shadow map, and the geometry of the cone of the spotlight.
There are a number of properties that can be used to change the geometry of the cone that composes the area of the spotlight. two major values that may come to mind are the angle of the cone, as well as the distance.
These can be used to set the geometry of the cone, in addition to that there are more values that have to do with the intensity of the light, and the penumbra of the spotlight.
If you want to see what is going on with the spotlight, by having a way of showing the current area of the cone with some lines, there is no need to make your own object for dong so. There is a special helper class in three.js just for this purpose. To use this helper I just need to create an instance of new THREE.SpotLightHelper and pass a reference to the spotlight that I want to use the helper with. I will then want to pass reference to the resulting spot like helper to the spotlights add method so that the helper is a child of the spotlight.
Te sport light helper then gives me a great idea of what is going on with the state of the spotlight, I can the adjust the various values for the spotlight until I get something that will work well with the project that I am working on.
There is much more to know about spotlights, and lights in general as well as the differences in the materials that respond to lights like the spotlight. As I author more content on three.js, and update more demos, I often get around to updating by older content on three.js now and then, and this post is no exception to this. When I first wrote this post back in 2018 I was using r91 of three.js, and a of this writing I was using r127, and it would look like not much of anything has changed when it comes to spotlights at least.
Yet another kind of light to work with in three.js is the point light that can be used to shine light in all directions from a given point in the scene. This is the kind of light that I often fine myself using in examples as I tend to like that kind of nature of the point light. There is also zeroing in a usual option when it comes to materials also, and with that I often like to go with the standard material I have my reasons why that get a little involved buy simple put it just strikes me as a well balanced material.