Defining Material Properties (Lighting) (OpenGL Programming)

You’ve seen how to create light sources with certain characteristics and how to define the desired lighting model. This section describes how to define the material properties of the objects in the scene: the ambient, diffuse, and specular color, the shininess, and the color of any emitted light. (See "The Mathematics of Lighting" for the equations used in the lighting and mate-rial-property calculations.) Most of the material properties are conceptually similar to ones you’ve already used to create light sources. The mechanism for setting them is similar, except that the command used is called glMaterial*().

void glMaterial[if}(GLenum face, GLenum pname, TYPE par am)·,

void glMaterial|if|v(GLenum face, GLenum pname, TYPE *param);

Specifies a current material property for use in lighting calculations, face can be GL_FRONT, GI._BACK, or GL_FRONT_AND_BACK to indicate to which faces of the object the material should be applied. The particular material property being set is identified by pname, and the desired values for that property are given by param, which is either a pointer to a group of values (if the vector version is used) or the actual value (if the nonvector version is used). The nonvector version works only for setting GL_SHININESS. The possible values for pname are shown in Table 5-3. Note that GL_AMBIENT_AND_DIFFUSE allows you to set both the ambient and diffuse material colors simultaneously to the same RGBA value.


Parameter Name

Default Value

Meaning

GL_AMBIENT

(0.2, 0.2, 0.2,

1.0)

ambient color of material

GL_DIFFUSE

(0.8, 0.8, 0.8,

1.0)

diffuse color of material

GL_AMBIENT_AND_DIFFUSE

ambient and diffuse color of material

GL_SPECULAR

(0.0, 0.0, 0.0,

1.0)

specular color of material

gl_shininess

0.0

specular exponent

GL_EMISSION

(0.0, 0.0, 0.0,

1.0)

emissive color of material

GL_COLOR_INDEXES

(0, 1, 1)

ambient, diffuse, and specular color indices

Table 5-3 Default Values for pname Parameter of glMaterial*()

As discussed in "Selecting a Lighting Model," you can choose to have lighting calculations performed differently for the front- and back-facing polygons of objects. If the back faces might indeed be seen, you can supply different material properties for the front and back surfaces by using the face parameter of glMaterial*(). See Plate 14 for an example of an object drawn with different inside and outside material properties.

To give you an idea of the possible effects you can achieve by manipulating material properties, see Plate 16. This figure shows the same object drawn with several different sets of material properties. The same light source and lighting model are used for the entire figure. The sections that follow discuss the specific properties used to draw each of these spheres.

Note that most of the material properties set with glMaterial*() are (R, G, B, A) colors. Regardless of what alpha values are supplied for other parameters, the alpha value at any particular vertex is the diffuse-material alpha value (that is, the alpha value given to GL_DIFFUSE with the glMaterial*() command, as described in the next section).

Diffuse and Ambient Reflection

The GL_DIFFUSE and GL_AMBIENT parameters set with glMaterial*() affect the colors of the diffuse and ambient light reflected by an object. Diffuse reflectance plays the most important role in determining what you perceive the color of an object to be. Your perception is affected by the color of the incident diffuse light and the angle of the incident light relative to the normal direction. (It's most intense where the incident light falls perpendicular to the surface.) The position of the viewpoint doesn't affect diffuse reflectance at all.

Ambient reflectance affects the overall color of the object. Because diffuse reflectance is brightest where an object is directly illuminated, ambient reflectance is most noticeable where an object receives no direct illumination. An object's total ambient reflectance is affected by the global ambient light and ambient light from individual light sources. Like diffuse reflectance, ambient reflectance isn't affected by the position of the viewpoint.

For real-world objects, diffuse and ambient reflectance are normally the same color. For this reason, OpenGL provides you with a convenient way of assigning the same value to both simultaneously with gIMaterial*():

tmp10a055_thumb

In this example, the RGBA color (0.1, 0.5, 0.8, 1.0)—a deep blue color— represents the current ambient and diffuse reflectance for both the front-and back-facing polygons.

In Plate 16, the first row of spheres has no ambient reflectance (0.0, 0.0, 0.0, 0.0), and the second row has a significant amount of it (0.7, 0.7, 0.7, 1.0).

Specula»· Reflection

Specular reflection from an object produces highlights. Unlike ambient and diffuse reflection, the amount of specular reflection seen by a viewer does depend on the location of the viewpoint—it is brightest along the direct angle of reflection. To see this, imagine looking at a metallic ball outdoors in the sunlight. As you move your head, the highlight created by the sunlight moves with you to some extent. However, if you move your head too much, you lose the highlight entirely.

OpenGL allows you to set the effect that the material has on reflected light (with GL_SPECULAR) and control the size and brightness of the highlight (with GL_SHININESS). You can assign a number in the range [0.0, 128.0] to GL_SHININESS: the higher the value, the smaller and brighter (more focused) the highlight.

In Plate 16, the spheres in the first column have no specular reflection. In the second column, GL_SPECULAR and GL_SHININESS are assigned values as follows:

tmp10a056_thumb

In the third column, the GL_SHININESS parameter is increased to 100.0.

Emission

By specifying an RGBA color for GL_EMISSION, you can make an object appear to be giving off light of that color. Since most real-world objects (except lights) don’t emit light, you’ll probably use this feature mostly to simulate lamps and other light sources in a scene. In Plate 16, the spheres in the fourth column have a reddish-gray value for GL_EMISSION:

tmp10a057_thumb

Notice that the spheres appear to be slightly glowing; however, they’re not actually acting as light sources. You would need to create a light source and position it at the same location as the sphere to create such an effect.

Changing Material Properties

Example 5-1 uses the same material properties for all vertices of the only object in the scene (the sphere). In other situations, you might want to assign different material properties for different vertices on the same object. More likely, you have more than one object in the scene, and each object has different material properties. For example, the code that produced Plate 16 has to draw 12 different objects (all spheres), each with different material properties. Example 5-8 shows a portion of the code in display().

Example 5-8 Different Material Properties: material.c

Different Material Properties: material.c

 

 

Different Material Properties: material.c

As you can see, glMaterialfv() is called repeatedly to set the desired material property for each sphere. Note that it needs to be called only to change a property that has to be respecified. The second, third, and fourth spheres use the same ambient and diffuse properties as the first sphere, so these properties do not need to be respecified. Since glMaterial*() has a performance cost associated with its use, Example 5-8 could be rewritten to minimize material-property changes.

Nate Robins’ Lightmaterial Tutorial

If you have downloaded Nate Robins’ suite of tutorial programs, now run the lightmaterial tutorial. With this tutorial, you can experiment with the colors of material properties, including ambient, diffuse, and specular colors, as well as the shininess exponent.

Color Material Mode

Another technique for minimizing performance costs associated with changing material properties is to use glColorMaterial().

void glColorMaterial(GLenum face, GLenum mode);

Causes the material property (or properties) specified by mode of the specified material face (or faces) specified by face to track the value of the current color at all times. A change to the current color (using glColor*()) immediately updates the specified material properties. The face parameter can be GL_FRONT, GLJBACK, or GL_FRONT_AND_BACK (the default). The mode parameter can be GL_AMBIENT, GL_DIFFUSE, GL_SPECUL<\R, GL_AMBIENT_AND_DIFFUSE (the default), or GL_EMISSION. At any given time, only one mode is active. glColorMaterial() has no effect on color-mdex lighting.

Note that glColorMaterial() specifies two independent values: the first determines which face or faces are updated, and the second determines which material property or properties of those faces are updated. OpenGL does not maintain separate mode variables for each face.

After calling glColorMaterial(), you need to call glEnable() with GL_ COLOR_MATERIAL as the parameter. Then, you can change the current color using glColor*() (or other material properties, using glMaterial*()) as needed as you draw:

tmp10a060_thumb

You should use glColorMaterial() whenever you need to change a single material parameter for most vertices in your scene. If you need to change more than one material parameter, as was the case for Plate 16, use glMaterial*(). When you don’t need the capabilities of glColorMaterialO anymore, be sure to disable it so that you don’t get undesired material properties and don’t incur the performance cost associated with it. The performance value in using glColorMaterial() varies, depending on your OpenGL implementation. Some implementations may be able to optimize the vertex routines so that they can quickly update material properties based on the current color.

Example 5-9 shows an interactive program that uses glColorMaterial() to change material parameters. Pressing each of the three mouse buttons changes the color of the diffuse reflection.

Example 5-9 Using glColorMaterialQ: colormat.c

Using glColorMaterialQ: colormat.c

 

 

 

Using glColorMaterialQ: colormat.c

 

 

Using glColorMaterialQ: colormat.c

Try This

Modify Example 5-8 in the following manner:

•    Change the global ambient light in the scene. Hint: Alter the value of the GL_LIGHT_MODEL_AMBIENT parameter.

•    Change the diffuse, ambient, and specular reflection parameters, the shininess exponent, and the emission color. Hint: Use the glMaterial*() command, but avoid making excessive calls.

•    Use two-sided materials and add a user-defined clipping plane so that you can see the inside and outside of a row or column of spheres.

•    Remove the glMaterialfv() call for setting the GL_DIFFUSE value, and use the more efficient glColorMaterial() calls to achieve the same lighting.

Next post:

Previous post: