November 8, 2007
By Richard G. Baldwin
Alice Programming Notes # 200
Creating scenes that appear to be three-dimensional on a flat two-dimensional screen is all about creating optical illusions. There are many important aspects to creating these optical illusions in 3D programming, not the least of which is lighting and illumination.
This document presents a relatively brief explanation of how to use the lighting and illumination features that are available in Alice. For a much more extensive discussion of lighting and illumination issues in 3D programming, see the document titled Understanding Lighting in the Java 3D API in Resources.
I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.
Once you have mastered Alice, I recommend that you also study the other lessons in my extensive collection of online programming tutorials. You will find a consolidated index at www.DickBaldwin.com.
No documentation available
As of the date of this writing, there is essentially no documentation available for Alice 2.0 except for commercial textbooks and the online tutorials that I have published (see Resources). Therefore, everything in this document is based on my experimentation with Alice 2.0.
Illumination of objects
With one exception, the illumination of objects in 3D programming is usually based on code that models:
The use of emissiveColor
The exception mentioned above is often called emissive light or emissiveColor. This is self-illumination that is generated by an object in the absence of other light sources. An example might be an object that glows in the dark such as a pumpkin (Halloween decoration) or a paper bag (Christmas decoration) containing a candle.
Figure 1 shows an IceSkater object illuminated only by green emissive light.
Figure 1. An IceSkater object illuminated only by green emissive light.
Not a source of light
Generally speaking, even though emissive light will cause an object to self-illuminate and to be visible in an otherwise dark environment, 3D programs usually don't allow emissive light to illuminate other nearby objects. (That contradicts my pumpkin and paper bag analogies above, which may illuminate other nearby objects.) I will demonstrate this characteristic of emissive light later.
Reflection of light from an object
The manner in which light is reflected from an object can be quite complex involving many attributes of the object's surface. I discuss some of these issues in detail in the earlier document, and will show you how to deal with some of them using Alice in this lesson.
Six types of light sources in Alice
I believe that there are six types of light sources that can be brought to bear in an Alice 2.0 program (but there may be others that I haven't discovered yet). Three of these types are classes in the gallery. Multiple objects can be created these three classes allowing for a very large number of actual light source objects. The six types are:
Note that although the default light, the ambient light, and the DirectionalLight have the ability to illuminate other objects, they have no visual manifestation in their own right. While it is possible to expose the bounding box and the axes for the default light and the DirectionalLight, they are always invisible. (There is no bounding box and axes associated with the ambient light.)
The ambient light can be thought of as being analogous to the light that exists outside on a very overcast day. It appears to come from everywhere simultaneously and it illuminates every exposed surface on all visible objects.
Objects of the classes LightBulb and StageSpotLight
Objects instantiated from the LightBulb and StageSpotLight classes do have a visible manifestation. Each object created from these two classes actually consists of two objects, a main object and a sub-object, which is a child of the main object. The main object can be thought of as a visible housing for the light source and the sub-object can be thought of as an invisible source of light inside the housing.
The housing for a LightBulb object resembles a common incandescent light bulb. The housing for a StageSpotLight object resembles the lights that you sometimes see hanging above a stage in a theatre. The visible manifestations of objects of these two classes are shown in Figure 2.
Figure 2. Visual manifestation of LightBulb and StageSpotLight objects.
The color and brightness properties of a light source
You can control the color of all six light sources including the emissive light. You can control the brightness of all but the emissive light. You can control various other properties (such as range and attenuation) of the default light, the DirectionalLight, the LightBulb, and the StageSpotLight.
DirectionalLight and default light may be the same type
An object of the DirectionalLight class seems to produce illumination that is very similar to the default light. It may be that the default light is simply an object of the DirectionalLight class that is automatically created when you create a new world.
The pointOfView of a light source
You can control the pointOfView (position and orientation) of all of the light sources other than the ambient light and the emissive light. However, an object of the LightBulb class appears to transmit light equally in all directions, so modifying the orientation aspect of the pointOfView has no impact on the way that a LightBulb object illuminates other objects.
Similarly, the light emitted by the default light and the DirectionalLight seems to behave as if the source is so far out in space that the light rays are parallel (similar to the sun in our solar system). Consequently, it doesn't seem to matter how far you position those two light sources away from the object being illuminated. The illumination doesn't seem to change as a function of distance to the source. Both of these sources have a range property that would lead one to believe that there is a maximum allowable distance between the light source and the object being illuminated. However, this property doesn't seem to have any impact on the manner in which the light illuminates the object, so I don't know what it is used for.
The directional light sources
The default light, the DirectionalLight, and the StageSpotLight are all directional lights. You have more control over the beam width and other aspects of the light from a StageSpotLight than from the other two directional lights. If you really want to set up some fancy lighting in your scene, you may want to consider the use of one or more objects of the StageSpotLight class.
Alice objects do not cast shadows on other objects. If you want it to appear that an object is casting a shadow, you must construct the shadow as a separate object as shown by the black elliptical circle on the ground in Figure 13. Creating a shadow for a sphere as shown in Figure 13 is a relatively easy task. However, creating a shadow for a more complex object, such as an object of the Bunny class, would be a more difficult task.
Reflection of light from objects
The properties of an Alice object that appear to have the greatest impact on the light reflected from the object are:
The effect of the color property
Assuming that emissive light is turned off, the appearance of an illuminated object (from the viewpoint of color) depends on the interaction of the original color in which the artist painted the model, the color property of the object, and the color properties of the light sources that are illuminating the object.
Sixteen million colors
The original color of every object and the value of the color property of every object in Alice are some combination of various amounts of red, green, and blue (the primary colors). The amount of each primary color can range from a value of zero to a value of 255. Theoretically, it is possible to generate more than sixteen million unique colors, one for each unique combination of the 256 values of each primary color.
There are several available ways to specify a color, ranging from simply clicking on a color that you like to adjusting sliders in order to specify the values of the red, green, and blue components of the desired color.
A serious limitation
Note, however, that as near as I have been able to determine, you cannot write code to set the red, green, and blue component values at runtime to values that you did not establish when you wrote the program. For example, I have found no way to use an integer value obtained from a random number generator to set the value of the red component of a color property, or a variable of type color at runtime.
White and black
The color white contains the maximum amount of all three primary colors. The color black contains no amount of any of the three primary colors.
The reflection color
The visible color of the object results from an interaction of the original color provided by the artist, the value of the color property of the object, and the color property of the light that illuminates the object.
An object reflects the primary color components contained in a light source in direct proportion to the amounts of the corresponding primary color components in the color of the object.
For example, if the color of an object contains only the primary color red, and a light source contains only the primary colors green and/or blue, an attempt to illuminate the object with the light source will result in a black object. This is because the primary color components of the object are absent from the primary color components of the light source.
As another example, if an object is yellow, (consisting of equal amounts of red and green), illuminating the object with a red light source will make it appear to be red. Illuminating the object with a green light source will make it appear to be green. Illuminating it with a light source that contains equal amounts of red and green (yellow or white) will make it appear to be yellow. However, illuminating it with a blue light will make it appear to be black.
The visible color of an object
It is important to realize that in most cases, the visible color of an object is not completely determined by the interaction of the color property of the object and the color property of the light source. The artist who created the 3D model will normally have used various different colors to paint the different parts of the model.
When the value of the color property of the object is anything other than white, the visible colors of the different parts of the object are determined by an interaction between the value of the color property of the object, the color property of the light source, and the colors that the artist used to paint the model. However, I cannot explain in detail how that interaction is implemented.
The effect of the color used by the artist is not an issue in those cases where the artist elected to paint the model white, as is the case for most of the classes in the Shapes thumbnail. When the artist painted the model white, its visible color is completely determined by the interaction between the color property of the object and the color property of the light source.
If the color property of the object is white, the visible color of the object will be determined by the color property of the light source and the colors that were used by the artist to paint the model.
If the color property of the object is black, the visible color of the object will be black regardless of the color property of the light source and the colors used by the artist to paint the object.
A word of caution
When experimenting with lights and colors, it is important to remember that by default, the scene is illuminated by the ambient light of the world (colored gray) and the default light object. Don't forget to set the brightness property of one of these sources to zero while experimenting with the other source. Otherwise, things can seem to be very confusing.
The effect of specular reflection
Many Alice objects have the following properties, which have an important impact on the object's appearance when it is illuminated by a light source other than emissive light or ambient light.
What is specular reflection?
One good way to understand specular reflection is to contrast it with diffuse reflection. Here is part of what Wikipedia has to say on the topic:
"Specular reflection is the perfect, mirror-like reflection of light ... from a surface, in which light from a single incoming direction is reflected into a single outgoing direction. Such behaviour is described by the law of reflection, which states that the direction of outgoing reflected light and the direction of incoming light make the same angle with respect to the surface normal; this is commonly stated as θi = θr.
This is in contrast to diffuse reflection, where incoming light is reflected in a broad range of directions. The most familiar example of the distinction between specular and diffuse reflection would be matte and glossy paints. While both exhibit a combination of specular and diffuse reflection, matte paints have a higher proportion of diffuse reflection and glossy paints have a greater proportion of specular reflection. Very highly polished surfaces, such as high quality mirrors, can exhibit almost perfect specular reflection."
Note that Alice does not provide direct control over diffuse reflection, but the specularHighlightExponent property makes it possible to simulate the effects of diffuse reflection. Specifying lower values for this property makes the reflection appear to be more diffuse.
I will show you an example of specular reflection later in this lesson (see Figure 12).
The effect of the shadingStyle property
The 3D optical illusion is mainly created by shading different parts of a 3D object to indicate the extent to which each part is illuminated by a given source of light. This is illustrated by the large yellow sphere in Figure 13, and is also illustrated by the dark gray housing on the spotlight in Figure 2.
Intersecting polygons and the shadingStyle property
Each 3D object in Alice (and many other programs that use 3D models) is modeled as a set of intersecting flat polygons. (Intersecting triangles are often used for this purpose.) The shadingStyle property determines how each of the polygons is colored, which in turn determines the overall appearance of the 3D object. The shadingStyle property can be given any of the following three values:
The 3D effect produced by shading is accomplished by varying the color of each polygon in relation to the extent to which it is illuminated. The extent to which the polygon is illuminated is determined by the angle between the incident rays from the light source and the plane of the polygon. When the direction to the light source is perpendicular to the plane of the polygon, the illumination is maximum. As the angle decreases, the illumination also decreases. When the light rays are parallel to the plane of the polygon, the polygon is not illuminated.
For example, a polygon that is positioned on an object such that the plane of the polygon is parallel to the light rays, or a polygon on the back side of an object that is hidden from the light source will often be colored black or dark gray. A polygon whose plane is perpendicular to the light rays and is fully illuminated will be a bright version of the color originally applied to that polygon by the artist who created the 3D model.
Color varies across each polygon
When SMOOTH shading is used, the actual color of each polygon will vary over the surface of the polygon in such a way that the colors of the intersecting edges of two adjacent polygons are nearly the same. The effect is to prevent the intersections of the polygons from being obvious and to give the object a smooth overall 3D appearance even though it is constructed from intersecting flat polygons.
There are several approaches to smooth shading, some of which are more effective than others. Also, some of them place a greater computational load on the computer than others. I explain some of the different approaches in the earlier document on lighting using Java3D.
SMOOTH shading on an IceSkater object
Figure 3 shows three IceSkater objects that were rendered using SMOOTH shading. The orientation of each object relative to the position of the light source is different, causing the polygons that make up the model to be colored differently in each of the three cases.
Figure 3. SMOOTH shading on an IceSkater object.
Polygons are not obvious
Although there are some apparent discontinuities at the knee and shoulder joints, the polygons that make up this model are not obvious. Contrast this with the image in Figure 4 where the use of FLAT shading causes the polygons to be very obvious.
The objects in Figure 3 were illuminated by the default dark gray ambient light source plus the default white directional light source.
When FLAT shading is used, the color of each polygon is constant over the entire surface of the polygon. Adjacent polygons are often different colors. This usually causes it to be visually obvious that the object is constructed from flat polygons. While this often results in a less pleasing appearance than smooth shading, it is worth noting that for most systems, this will also reduce the computational load that shading imposes on the computer.
Figure 4 shows the same three IceSkater objects as were shown in Figure 3. However, whereas the objects in Figure 3 were rendered using SMOOTH shading, the objects in Figure 4 were rendered using FLAT shading.
Figure 4. FLAT shading on an IceSkater object.
Comparing Figure 4 with Figure 3 should give you some idea how the polygon colors in Figure 4 were smoothed into one another to produce smooth color gradients in Figure 3.
As in Figure 3, the objects in Figure 4 were illuminated by the default dark gray ambient light source plus the default white directional light source.
When a shading value of NONE is used to render the object, the polygons aren't shaded at all. Assuming that the object is illuminated with white light, each polygon is displayed in the color originally given to that polygon by the artist who created the model. Typically, this will destroy the 3D optical illusion causing the object to appear to be a flat drawing.
Figure 5 shows one example of each of the three types of shading available in Alice.
Figure 5. FLAT, SMOOTH, and NONE shading on an IceSkater object.
The IceSkater object in the center was rendered using SMOOTH shading. The object on the left was rendered using FLAT shading. The object on the right was rendered using a shading value of NONE. The default gray ambient light was turned off in Figure 5. This caused the objects to be illuminated by the single default directional white light source. This had the effect of causing the shading to be more pronounced than in Figure 3 and Figure 4.
The main point in Figure 5 is that the 3D optical illusion has been lost for the object with no shading on the right.
This lesson will present and explain four Alice programs that illustrate the concepts discussed above. The program named Lights03 illustrates the use of emissiveColor to self-illuminate an object, and to show that it doesn't illuminate nearby objects.
The program named Lights02 illustrates the interaction between the color property of an object and the color property of the light illuminating the object.
The program named Lights04 illustrates specular reflection.
The program named Lights05:
Figures 6 through 9 show screen shots taken from the program named Lights03. A complete listing of this program is shown in Listing 1. Figure 6 shows a screen shot from the program at startup.
Figure 6. Screen shot from Lights03 at startup.
Illumination by default light source only
As the text in Figure 6 indicates, the scene in Figure 6 is being illuminated solely by the default light source. The ambient light has been turned off. The emissive light is off, and no other light sources have been added to the scene.
Also as shown in the code in Listing 1, the color property for the sphere and each of the cones was set to red.
Emissive light turned on
Figure 7 shows a screen shot after the emissiveColor property for the sphere has been set to yellow. The scene in Figure 7 is still being eliminated solely by the default light.
Figure 7. Screen shot from Lights03 with emissiveColor property for the sphere set to yellow.
Turn default light off
Figure 8 shows a screen shot after the default light has been turned off. This leaves only the emissiveColor for the sphere turned on.
Figure 8. Screen shot from Lights03 with only emissiveColor turned on.
The two cones are not illuminated
The important thing to note in Figure 8 is that even though the two cones are still next to the sphere, the emissiveColor light from the sphere does not eliminate the cones.
Turn the ambient light on
Figure 9 shows a screen shot of the same scene with the scene being illuminated by white ambient light and by emissiveColor light from the sphere. (The default light is still turned off.)
Figure 9. Screen shot from Lights03 with white ambient light turned on.
The ambient light causes the ground as well as the two cones to be illuminated. The sphere and the two cones appear to be flat two-dimensional drawings because there is no shading of the polygons. The red color of the cones is not affected by the yellow emissiveColor light from the sphere.
A complete listing of this program is provided in Listing 2.
This program illustrates the interaction between the color property of an object and the color property of the light illuminating the object as explained earlier. In this case, the objects of interest are spheres from the Shapes thumbnail, which were originally painted white by the artist.
The program begins by arranging and coloring seven spheres as shown in Figure 10.
Figure 10. Arrangement and colors of the spheres in Lights02.
The color property values for the spheres
The spheres in Figure 10 were illuminated by a single source of white light. Thus, the colors shown in Figure 10 represent the color property values of the spheres:
The numbers in parentheses in the above list represent the amounts of red, green, and blue respectively in each color property value. The names of the secondary colors (yellow, aqua, and magenta) came from the web page titled RGB to Color Name Mapping (see Resources).
Illuminate the spheres
Once the spheres were arranged and their color property values were set, they were illuminated by a single default light. The color property value of the light was cycled through each of the color values shown in the above list. The appearance of the spheres for a white light is shown in Figure 10. The appearance of the spheres for each of the remaining six colors of light is shown in Figure 11.
Figure 11. Appearance of the spheres for six different light colors.
The spheres reflect different colors of light
The six images going from left to right, top to bottom in Figure 11 show the appearance of the seven spheres for light colors beginning with red and progressing through magenta in the order shown above.
As shown in the upper left corner of Figure 11, when the spheres were illuminated with pure red light, three of the spheres disappeared into the black background. The four spheres with the following color property values were visible and appeared to be red:
These four spheres were visible because the color property value of each of these spheres contains a red component at a full intensity value of 255.
Illuminate with a yellow light
As shown in the upper right corner of Figure 11, when the spheres were illuminated with a yellow light, only one sphere disappeared into the black background. The magenta and red spheres appeared to be red. The white and yellow spheres appeared to be yellow and the aqua and green spheres appeared to be green.
This occurred because:
Similar color patterns occurred for each of the six illumination colors.
Different colors for each sphere
The white sphere in the center of the arrangement in Figure 10 was always visible exhibiting the same color as the light.
Starting with the red sphere in Figure 10 (sphere0) and going counter-clockwise around the arrangement, the six outer spheres took on the following colors in Figure 11:
It is important to note that at no time did the actual color property of any of the spheres change during this sequence. Once the color property of a sphere was set, it was never changed. Only the color property of the illuminating light changed. Thus, it is possible to make it appear that objects change colors simply by changing the color of the light source that is being used to illuminate the objects. This might be a useful technique for simulating the lights on a space ship.
A complete listing of this program is provided in Listing 3. This program illustrates specular reflection as described earlier.
Figure 12 (left to right, top to bottom) shows four snapshot renderings of a sphere as the light source circled the sphere disappearing behind the sphere on the left side and emerging from behind the sphere on the right side. Each image shows a specular reflection.
Figure 12. Illustration of specular reflection in Lights04.
The ambient light was turned off and the ground was made invisible in Figure 12. The color property of the sphere was white and the color property of the light was red. Hence, the sphere appeared to be red.
The specular reflection property values
The specularHighlightColor property of the sphere was set to red and the specularHighlightExponent value was set to 1000. Up to a point, the higher the value of the specularHighlightExponent property, the shinier will be the object and the smaller will be the size of the specular reflection. However, the minimum size of the specular reflection is limited by the size of the intersecting polygons that make up the surface of the object, so increasing the value beyond 1000 in this case made very little difference.
I recommend that you experiment with these property values in order to understand their impact on the rendered output.
Behavior of the program
Once the stage was set, a statement in the main method caused the light to make one complete revolution around the sphere with the light beam aimed at the sphere at all times. This in turn caused the specular reflection to move around the sphere from right to left, disappearing behind the sphere on the left and re-emerging from behind the sphere on the right.
Screen shots from this program are shown in Figure 13. A complete listing of the program is provided in Listing 4.
The purpose of this program is to:
Illuminating the scene
Figure 13 shows eight screen shots from two successive runs the program taken while each of the light sources listed above was the only source of illumination for the scene. The small red sphere in the right side of each image shows the position of the light source.
The position of the light sources
The position of each light source was relatively far from the surface of the large yellow sphere in the images in the left column of Figure 13. The position of each light source was very close to the surface of the large yellow sphere in the images in the right column.
Figure 13. Screen shots from the program named Lights05.
The small red sphere
The purpose of the small red sphere was to mark the position of the light sources. The emissive color of the small sphere was set to red so that it would always be visible, even when it wasn't being illuminated by one of the light sources.
The shadow was constructed by positioning a black circle shape on the ground slightly to the left of and slightly behind the large yellow sphere. As mentioned earlier, it was relatively easy to create an artificial shadow for a sphere. It would be much more difficult to create an artificial shadow for a more complex object such as an IceSkater.
The shadow is fairly realistic for the default light and the directionalLight. However, it is completely unrealistic for the lightBulb and the stageSpotLight.
The ambient light
The world's ambientLightBrightness property was set to 0 to ensure that the only illumination in the scene at any particular time was produced by one of the four light sources listed earlier.
Controlling the light sources
The brightness property of each light source was initially set to 0. Each light source was moved, (one at a time), to the position of the red sphere and pointed at the center of the large yellow sphere. Following that, the light source was turned on slowly, by setting the value of the brightness property to 1.5 with a duration of three seconds. Then a two-second pause was inserted to make it possible to capture a screen shot of the scene. Then the light source was turned off slowly by setting the value of the brightness property to 0 with a duration of three seconds.
The lightBulb is non-directional
Because the lightBulb source is not directional, it was not pointed at the sphere after being moved into position.
The stageSpotLight has other control parameters
In addition to the brightness property, the stageSpotLight has an innerBeamAngle property and an outerBeamAngle property. These properties are used to control the width of the light beam emitted by the spot light. These two properties were set to 0.3 and 0.6 radians respectively. I recommend that you experiment with these parameters to get a feel for how they affect the manner in which this source will illuminate an object.
Changing the position of the light sources
The program code in Listing 4 shows that the position of each light source as well as the position of the small red sphere was controlled by a single statement that sets the value of a variable named lightPosition. The different results shown in the left and right columns of Figure 13 were achieved by changing the literal values in this statement and re-running the program.
The default light and directionalLight sources
Consider the four images at the top of Figure 13. Because the manner in which the two light sources illuminate an object, we can conclude that the default light that appears whenever you create a new world is probably an object of the directionalLight class in the gallery. If we need additional light sources having those characteristics, we can instantiate them using the class from the gallery.
We can also conclude that the manner in which either the default light or an object of the directionalLight class illuminates an object is independent of the distance from the light source to the surface of the object being illuminated. It appears that regardless of that distance, the illumination appears to be from a source very far out in space (similar to our sun). Note, for example, that even though the light source was positioned at the location of the small red sphere, the upper right side of the small red sphere was illuminated in the same way that the upper right side of the large yellow sphere was illuminated. This could only happen if the true position of the light source was further from the yellow sphere than the position of the red sphere.
Thus, the manner in which an object is illuminated depends on the orientation angle of the light, but is independent of the distance to the light. Even knowing that, however, it is sometimes difficult to predict how one of these two light sources will illuminate an object. You should experiment with the position and orientation of the default light or an object of the directionalLight class.
The lightBulb source
Consider the two images in the third row in Figure 13 where the source of illumination is identified as a lightBulb. The manner in which an object is illuminated by a lightBulb source seems to be fairly consistent with what we would expect. All objects near to the source appear to be illuminated independent of the direction from the light source to the object. The illuminated area on the sphere decreases as the source moves closer to the sphere. Although it is not shown here, the intensity with which an object is illuminated appears to decrease as the distance from the object to the source increases, but that effect is not nearly as pronounced as might be expected.
Note that the simulated shadow in Figure 13 is totally unrealistic for a lightBulb source. The size of the shadow remains constant regardless of the relative positions of the yellow sphere and the light. In reality, the size of the shadow should increase as the lightBulb gets closer to the sphere.
The stageSpotLight source
The stageSpotLight source is the most versatile of all of the available light sources. The light emitted by this source is a directional cone. The width of the cone is controlled by two properties, each of which is specified by an angle in Radians: innerBeamAngle and outerBeamAngle. Since there is no documentation, the exact purpose of these two properties and the relationship between them isn't exactly clear. However, it is easy to show that the width of the cone increases when the specified width of the outerBeamAngle increases.
The bottom two images in Figure 13 show the effect of the illuminating cone. The illuminated area on the surface of the sphere is the size of the area described by the intersection of the surface and the cone. When the spot light source is very close to the surface of the sphere, the illuminated area is very small. When the source is further from the sphere, the illuminated area is larger.
Executable versions of the programs that I explained in this lesson are available for downloading (see Resources). I encourage you to either download those programs, or copy the code from Listings 1 through 4 into your Alice development environment and play it. Experiment with it, making changes to the various property values, and observing the results of your changes. In particular, you might want to experiment with the range, attenuation, angles, and etc. properties.
In this lesson, I taught you how to use emissive color, ambient light, the default light, a directional light, a light bulb, and a spot light to illuminate your Alice world. I also taught you how to use shading, color, and specular reflection in your illumination scheme, as well as how to create shadows.
Resources from earlier lessons in the series titled "Learn to Program using Alice"
Listing 1. The program named Lights03.
Created by: Dick Baldwin
Listing 2. The program named Lights02.
Created by: Dick Baldwin
Listing 3. The program named Lights04.
Created by: Dick Baldwin
Listing 4. The program named Lights05.
Created by: Dick Baldwin
Copyright 2007, Richard G. Baldwin. Faculty and staff of public and private non-profit educational institutions are granted a license to reproduce and to use this material for purposes consistent with the teaching process. This license does not extend to commercial ventures. Otherwise, reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.
Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas. He is the author of Baldwin's Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.
In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP). His first job after he earned his Bachelor's degree was doing DSP in the Seismic Research Department of Texas Instruments. (TI is still a world leader in DSP.) In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.
Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.