HTML and CSS Reference
In-Depth Information
norm.y * this.light.y +
norm.z * this.light.z;
As you can see, dot products are a bit simpler than cross products!
Next, you calculate the magnitude of the normal and the magnitude of the light, which you might recognize
as the 3D version of the Pythagorean Theorem:
var normMag = Math.sqrt(norm.x * norm.x +
norm.y * norm.y +
norm.z * norm.z);
var lightMag = Math.sqrt(this.light.x * this.light.x +
this.light.y * this.light.y +
this.light.z * this.light.z);
This
lightMag
variable is calculated every time a triangle is rendered, which allows for a moving light
source. If you know that the light source is going to be fixed, you can create this variable at the beginning
of the code and calculate it one time as soon as the light is created or assigned to the triangle.
Alternatively, you can add a
lightMag
property to the
Light
class. This can be calculated any time its x,
y, or z properties changed.
Finally, you take all these pieces you just calculated, and put them into the magic formula:
return (Math.acos(dotProd / (normMag * lightMag)) / Math.PI) * this.light.brightness;
Basically,
dotProd
is one measurement and
(normMag * lightMag)
is another. Dividing these two gives
you a ratio. Recall from our discussion in Chapter 3 that the cosine of an angle gives you a ratio, and the
arccosine of a ratio gives you an angle. So using
Math.acos
here on this ratio of measurements gives you
an angle. This is essentially the angle at which the light is striking the surface of the polygon. It is in the
range of 0 to
Math.PI
radians (0 to 180 degrees), meaning it's either hitting head on or completely from
behind.
Dividing this angle by
Math.PI
gives you a percentage, and multiplying that by the percentage of
brightness gives you your final light factor, which you use to alter the base color.
All this was just to get a new color for the surface! Implementing it in your existing code is pretty easy—you
add it to the
draw
method of the
Triangle
class. Instead of using the base color, use the adjusted color,
like so:
context.fillStyle = context.strokeStyle = this.getAdjustedColor();
To wrap things up, here is the complete and final code for
triangle.js
and the document
03-extruded-
a-light.html
.
First, here's the
Triangle
class:
function Triangle (a, b, c, color) {
this.pointA = a;
this.pointB = b;
this.pointC = c;
this.color = (color === undefined) ? "#ff0000" : utils.parseColor(color);
this.lineWidth = 1;
this.alpha = 1;