CS307: Material and Lighting
Plan
- Surface materials, reflectance, lights
- ambient, diffuse, specular
- Lambert and Phong models
- Materials and light sources in Three.js
- Exercises: pink ball, golden treasure, add light bulb to Luxo
Compelling 3D Surfaces with Material & Lighting
By modeling different kinds of surface materials and how they reflect light, we can create a more compelling three-dimensional appearance of object surfaces, as illustrated in this picture from the Wikipedia page on the Phong model
What is the difference between local and global lighting models?
As we summarize how surface materials and scene lighting are modeled, we will refer to these slides.
Ambient Calculations
Independent of any light source other than a global ambient
Diffuse Calculation
- LV is the vector from the surface fragment to the light
- NV is the surface normal (a vector) of the surface fragment
- The dot product shows how closely LV and NV are aligned
Specular Calculation
- EV is the vector from the surface fragment to the eye
- RV is the vector from the surface fragment in the direction of perfect reflection (angle of incidence equals angle of reflection)
- the dot product between the two vectors shows how closely these are aligned
- shininess is a scalar, the exponent that the dot product is raised
to. A larger exponent
- causes the shine to diminish more quickly, so
- a smaller range of angles get a specular reflection.
- This makes the specular highlight smaller, and
- the object looks shinier.
The Complete Lambert Model
The Lambert model takes into account the surface normal and the angle towards the light:
I = Lamb Ramb + Ldiff Rdiff
Abstract Lambert Model
Filling in the details of mathematical models, we get:
I = Lamb kamb + Ldiff kdiff (LV • NV)
Concrete Lambert Model
The Complete Phong Model
Adding specularity to the Lambert model gives us the Phong model:
I = Lamb Ramb + Ldiff Rdiff + Lspec Rspec
Abstract Phong Model
Filling in mathematical models, we get:
I = Lamb kamb + Ldiff kdiff (LV • NV) + Lspec kspec (EV • RV)e
Concrete Phong Model
Quiz Questions
Let's look at the quiz questions.
Material and Lighting Tutor
We'll spend some time with an imitation of Nate Robins' tutor for
material and lighting. Note that the emissive property of the
material, controlled with the matEmissive
parameter in the
demo, is the color that the material emits. It doesn't act as
a real light source, but is a solid color that is not affected by other
lighting in the scene.
Materials and Light Sources in Three.js
Materials with Lambertian or Phong reflectance properties can be created in Three.js as follows:
var matLamb = new THREE.MeshLambertMaterial ( {color: THREE.ColorKeywords.cyan} ); var matPhong = new THREE.MeshPhongMaterial ( {color: THREE.ColorKeywords.green, specular: THREE.ColorKeywords.white, shininess: 30, flatShading: THREE.FlatShading } );
color
is the color of the surface for both materials. specular
is the color of specular highlights and shininess
is the exponent in the Phong model.
The graphics card can either
- interpolate the lighting calculations across a face (smooth shading), or
- it can use a single value for the entire face (flat shading)
You might think that smooth is always better than flat, but what if the geometry is not a polygonal approximation of a smooth object like a ball? What if, in fact, the geometry is accurate, and the object is faceted with flat faces, like a jewel?
See this,
from the Wikipedia page
on Phong Shading
You can implement flat shading by setting the flatShading
attribute for the
THREE.MeshPhongMaterial
to THREE.FlatShading
.
There are several kinds of light sources that we can add to a scene. The simplest are ambient, point, and directional light sources:
var ambientLight = new THREE.AmbientLight ( color, intensity ); scene.add(ambientLight); var pointLight = new THREE.PointLight ( color, intensity, distance, decay ); pointLight.position.set(50,50,50); scene.add(pointLight); var directLight = new THREE.DirectionalLight ( color, intensity ); // default positions of directional light and target directLight.position.set(0,1,0); directLight.target.position.set(0,0,0); scene.add(directLight); scene.add(directLight.target);
The default color
of light sources is white, and default
intensity
is 1. For THREE.PointLight
objects,
distance
is the distance from the light where intensity is 0; if set to
0 (the default), the light never stops. The Three.js documentation describes
decay
as "The amount the light dims along the distance of the light"
and its default value is 1.
All light-source classes are subclasses of the Light
class, which is a
subclass of Object3D
, which has a position
property that can be
set with position.set(x,y,z)
before adding the light source to the scene. For
a directional light, the combination of the position of the light and the position of
a target determine the direction of the light onto surfaces in the scene.
Spotlights have more parameters, and can also be directed toward a target location or object in the scene (the default target is the origin of the scene):
var spotLight = new THREE.SpotLight ( color, // rgb color of the source, default white intensity, // multiplication factor, default 1 distance, // distance where light ends, default 0 angle, // width of beam in radians, default Math.PI/2 penumbra, // % spotlight cone attenuated (0-1), default 0 decay // amount light decays with distance, default 1 ); spotLight.position.set(x,y,z); spotLight.target.position.set(xt,yt,zt); scene.add(spotLight); scene.add(spotLight.target);
If the desired target is a location other than the origin of the scene, the target (
spotLight.target
in this case) must be
added to the scene.
Let's explore this spotlight demo
Exercises: Pink Ball, Golden Treasure, and Luxo Lamp
Scott took these photos of his daughter's pink plastic ball:


Do you see the effects of specularity? If so, where?
Do you see the effects of diffuse reflection? If so, where?
Do you see the effects of ambient light? If so, where?
Exercise: Imitate the pink ball
Using this starter code, try to imitate the pink plastic ball.
Here's a GUI to help: pink ball GUI
Your final result might look something like this:
Here is a possible code solution: pinkBall.html
Exercise: Golden treasure
Using this starter code that displays a scene of solid gold-colored objects, modify the code to use Phong material and light sources to make the objects look more like shiny golden treasure (see "before" and "after" pictures below — you can probably do better than me!)
Real Luxo lamps have bulbs that emit light, as in this scene with Luxo Mom and Junior:
Exercise: Add a light source to the Luxo lamp
Starting with this luxo-bulb-start.html code file, complete these steps to add a spotlight for each Luxo lamp in the scene:
- Modify the materials stored in the
colorMaterials
array to be Phong materials instead of basic materials - Fill in the inputs to the
THREE.SpotLight()
constructor in the functionaddLuxoBulb()
that adds a spotlight to the scene for a Luxo lamp. You can mostly use default values here, but think about whatangle
to use in this case, based on the dimensions of the actual cone, and experiment with thepenumbra
value - Modify the position of
bulbTarget
in theaddLuxoBulb()
function - the target should be on the ground, at a distancedist
from the origin of the lamp(posX,0,posZ)
and at an angleangleY
(these variables are all defined in the code), as shown in the diagrams below: - Add two calls to the
addLuxoBulb()
function, to add bulbs for Mom and Junior
Your final code might look something like this: luxo-bulb-solution.html
Useful Facts about Material and Lighting
- Spotlights (and lights in general), are not affected by the
transformations that we apply to geometry. Therefore, it doesn't work
to add a light to, say, a clown's hat, and add that to the head, which
gets added to the body, and so forth. You should add your lights
directly to the scene, and use
global
coordinates when parameterizing them. - Lights have a boolean attribute,
.visible
. If they are not visible, they don't contribute to the scene. This makes them easy to turn on and off. You don't have to re-build anything, though you will need to re-render. - Spotlights only interact properly with
THREE.MeshPhongMaterial
, not withTHREE.MeshLambertMaterial
. This is not what the Three.js documentation says.
Preparation for Next Week
Next week, we'll talk about texture mapping which can give a surface a more realistic, photo-like appearance and enable you to create your own visual texture on a surface. To prepare:
- Reading for next week: Texture Mapping