\( \newcommand{\vecIII}[3]{\left[\begin{array}{c} #1\\#2\\#3 \end{array}\right]} \newcommand{\vecIV}[4]{\left[\begin{array}{c} #1\\#2\\#3\\#4 \end{array}\right]} \newcommand{\Choose}[2]{ { { #1 }\choose{ #2 } } } \newcommand{\vecII}[2]{\left[\begin{array}{c} #1\\#2 \end{array}\right]} \newcommand{\vecIII}[3]{\left[\begin{array}{c} #1\\#2\\#3 \end{array}\right]} \newcommand{\vecIV}[4]{\left[\begin{array}{c} #1\\#2\\#3\\#4 \end{array}\right]} \newcommand{\matIIxII}[4]{\left[ \begin{array}{cc} #1 & #2 \\ #3 & #4 \end{array}\right]} \newcommand{\matIIIxIII}[9]{\left[ \begin{array}{ccc} #1 & #2 & #3 \\ #4 & #5 & #6 \\ #7 & #8 & #9 \end{array}\right]} \)

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?

mirror reflection local lighting cast shadows

 

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 (LVNV)
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 (LVNV) + Lspec kspec (EVRV)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 Phong shading sample

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:

a pink plastic balla 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!)

    

golden objects solution

Real Luxo lamps have bulbs that emit light, as in this scene with Luxo Mom and Junior:

luxo family

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 function addLuxoBulb() that adds a spotlight to the scene for a Luxo lamp. You can mostly use default values here, but think about what angle to use in this case, based on the dimensions of the actual cone, and experiment with the penumbra value
  • Modify the position of bulbTarget in the addLuxoBulb() function - the target should be on the ground, at a distance dist from the origin of the lamp (posX,0,posZ) and at an angle angleY (these variables are all defined in the code), as shown in the diagrams below:

    bulb geometry

  • 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 with THREE.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: