Welcome back! In our previous tutorial Away3D TypeScript: Lights – PointLight, we simply placed a PointLight on the stage. It illustrated the principle of the light, but with no flare or flavor. In this tutorial, I wanted to showcase more of the 3D CGI beauty that PointLight is. You can view a larger version of the demo above here.
We will be recreating the scene as seen above.
Building off the previous tutorial, we’ll need to:
- Declare, instantiate, and initialize two new Mesh objects that will hold our two additional cubes.
- Declare, instantiate, and initialize a new SphereGeometry object that will represent our light bulb.
- Parent the new light bulb to our PointLight object.
- Create three variables to hold our temp red, green, and blue values.
- Create a variable to hold our compiled color value.
- Create a variable to count the frames as they tick by.
- On every frame, rotate our three cubes.
- On every frame, spin our PointLight around the scene.
- On every frame, adjust the strength (radius and falloff) of the PointLight.
- On every frame, adjust the size of the light bulb. We want it to grow and shrink with the strength of the PointLight
- On every frame, adjust the transparency of the light bulb. We want it to fade in and out with the strength of the PointLight
- On every frame, adjust the color of the PointLight and light bulb to match.
This tutorial builds off of the Away3D TypeScript: Lights – PointLight. All the new or changed code will be highlighted in the full code block below.
An error has occurred. Please try again later.
Line 5 renames the class to PointLightIntermediate.
Lines 20-21 two more Mesh objects labeled _objectMesh2 and _objectMesh3.
Line 23 declares a variable named _lightBulbGeom of type SphereGeometry.
Line 24 declares a variable named _lightBulb of type Mesh. This will be our visible light source.
Line 30 declares a variable named _frameCount of type Number. We will use this to phase between the colors of the spectrum. We start it at 100 to avoid some anomalies experienced at low numbers.
Lines 31-33 declares the variables named _red, _green, _blue of type Number. These will store the RGB colors we calculate later.
Line 34 declares a variable named _tempColor of type Number. This will store our complied RGB colors collectively.
Line 65 instantiates a new PointLight() object referenced by the variable _pointLight. It was initialized with nothing. No arguments are needed.
Line 66 sets the ambientColor node of the PointLight to 0xFFFFFF (white).
Line 67 sets the ambient strength to .05 or 5% if you prefer. Ambient light is the light that covers everything, not just where the PointLight is shining on.
Line 68 adds the PointLight object _pointLight to the scene.
Line 70 instantiates a new StaticLightPicker() object referenced by the variable _lightPicker. Then _pointLight was passed as the target of the StatickLightPicker(). *Note, as of this writing the StaticLightPicker required an array of arguments be passed. Even if it is just one item in the array. Hence why the included  brackts around [this._lightPicker]. As you may have guessed, you can pass multiple lights to influence a material.
Lines 87-90 and 92-95 duplicates the properties of our cube we’ve originally had in the scene. The only difference is that the Mesh objects are now labeled _objectMesh2 and _objectMesh3, as well as we shifted one cube 500 units to the left and the other cube 500 units to the right.
Line 97 instantiates a new SphereGeometry object referenced by the variable _lightBulbGeom. It was initialized with 20, 16, 16, true. A relatively small sphere.
Line 98 instantiates a new Mesh object referenced by the variable _lightBulb. Then _lightBulb‘s geometry was initialized with _lightBulbGeom.
Line 99 parents our _lightBulb object to the _pointLight object. Now the _lightbulb object will follow where ever the _pointLight object goes.
Line 112 increments our _frameCount variable by 1.
Lines 115-118 rotates our cube objects.
Lines 121-123 moves our PointLight around the scene in circles at a max of 250 units from the center. Different values are used for the x, y and z axis to create a more random flight pattern. So it is not the exact same flight pattern we also use _frameCount, since that number will never be the same twice.
Line 126 creates the effect of the PointLight pulsating in its intensity. It will get brighter and dimmer. More accurately, its sphere of influence expands and contracts. We add 10 so the light never fully turns off.
Line 127 multiplies the PointLight‘s radius by 10 to determine where the light’s falloff end. A light’s falloff is amount a light dims over a distance.
Line 130 calculates the X axis scale of the _lightBulb object to match the PointLight‘s size. We add .1 so the _lightBulb never shrinks below 10%.
Lines 131-132 keep the _lightBulb object’s Y and Z axises scale in proportion with the X axis.
Line 135 keeps the _lightBulb object’s alpha (transparency) in proportion with the bulb’s scaled size.
Lines 138-140 cycles through the numbers -255 and 225. We use different values, to create a more random pattern. We then store this number in there respective color.
Lines 142-144 apply some math to our stored color RGB channels. Math.abs makes sure it is a positive, not a negative number. Math.ceil makes sure it is a whole integer. Not decimals.
Line 143 takes each color and converts it to its Hex code. This is done by using .toString(16). Then we concatenate them together to get a Hex code RGB value, such as #FFFFFF (white). Finally we use parseInt((), 16) to convert the Hex code RGB value to a integer number. The number will be one of 16 Million shades of color in the digital color spectrum. This final value is stored in _tempColor.
Line 148 sets the _lightBulb’s material object’s color to the new stored _tempColor color.
Line 149 sets the PointLight object’s color to the new stored _tempColor color.
Line 175 changes the called class name to PointLightIntermediate.
That’s it, our light is lighting the scene.
However, we glazed over the initialization process, let’s take a closer look at the object’s constructor.
Points to Note
As you may have noticed, if the PointLight source is inside of an object, it does not illuminate that object. However, since we have not messed with any shadow settings and object, the other objects still receive light, even though the source is inside of another mesh.
Also, I wanted to mention, that most of the numbers used are arbitrary. The speed of the bulb moving, the speed at which the colors change, the rate of the strobe, etc… can be any value you find pleasing to the eye.
Experiment and send us a link to what you’ve made, we’d love to see it! Try adding more PointLights. Just remember to include them in the StaticLightPicker array.
Adding basic lighting is relatively easy. Just remembering to assign the light to a lightPicker and the lightPicker to a material’s lightPicker node, is the hardest part. You can look at the official documentation here.