Specular Lighting

DirectX8

 
Microsoft DirectX 8.1 (C++)

Specular Lighting

Modeling specular reflection requires that the system not only know the direction that light is traveling, but also the direction to the viewer's eye. The system uses a simplified version of the Phong specular-reflection model, which employs a halfway vector to approximate the intensity of specular reflection.

The default lighting state does not calculate specular highlights. To enable specular lighting, be sure to set the D3DRS_SPECULARENABLE to TRUE.

Specular Lighting is described by the following equation.

Specular Lighting = Vs*sum[Ls*(N.H)P*Atten*Spot] 
The parameters are defined in the following table.
ParameterDefault value TypeDescription
Vs(0,0,0,0) D3DCOLORVALUEVertex specular color. sumN/A N/ASummation of each light's specular component. NN/A D3DVECTORVertex normal. H(0,0,0,0) D3DCOLORVALUEHalf way vector. P(0,0,0,0) D3DCOLORVALUESpecular reflection power. Range is -infinity to +infinity Ls(0,0,0,0) D3DCOLORVALUELight specular color. Atten(0,0,0,0) D3DCOLORVALUELight attenuation. Spot(0,0,0,0) D3DVECTORCharacteristics of the spotlight cone.

The value for Vc is one of three values: one of the two possible vertex colors in a vertex declaration, or the material specular color. The value is:

  • vertex color1, if SPECULARMATERIALSOURCE = D3DMCS_COLOR1, and the first vertex color is supplied in the vertex declaration.
  • vertex color2, if SPECULARMATERIALSOURCE = D3DMCS_COLOR2, and the second vertex color is supplied in the vertex declaration.
  • material specular color

Note: If either SPECULARMATERIALSOURCE option is used, and the vertex color is not provided, then the material specular color is used.

To calculate the attenuation (Atten) or the spotlight characteristics (Spot), see Attenuation and Spotlight Terms

The halfway vector (H) exists midway between the vector from an object vertex to the light source and the vector from an object vertex and the camera position. Microsoft® Direct3D® provides two ways to compute the halfway vector. When D3DRS_LOCALVIEWER is set to TRUE, the system calculates the halfway vector using the position of the camera and the position of the vertex, along with the light's direction vector. The following formula illustrates this.

H = norm(norm(Cp - Vp) + Ldir) where the parameters are defined in the following table:

ParameterDefault value TypeDescription
Cp(0,0,0,0) D3DVECTORCamera position. Vp(0,0,0,0) D3DVECTORVertex position. Ldir(0,0,0,0) D3DVECTORDirection vector from vertex position to the light position.

When D3DRS_LOCALVIEWER is set to TRUE, Direct3D determines the halfway vector by the following formula.

H = norm(norm(- Vp) + Ldir)

Determining the halfway vector in this manner can be computationally intensive. As an alternative, setting D3DRS_LOCALVIEWER to FALSE instructs the system to act as though the viewpoint is infinitely distant on the z-axis. This setting is less computationally intensive, but much less accurate, so it is best used by applications that use orthogonal projection.

Specular components are clamped to be from 0 to 255, after all lights are processed and interpolated separately.

Example

In this example, the object is colored using the scene specular light color and a material specular color. The code is shown below.

D3DMATERIAL8 mtrl;
ZeroMemory( &mtrl;, sizeof(D3DMATERIAL8) );

D3DLIGHT8 light;
ZeroMemory( &light;, sizeof(D3DLIGHT8) );
light.Type = D3DLIGHT_DIRECTIONAL;

D3DXVECTOR3 vecDir;
vecDir = D3DXVECTOR3(0.5f, 0.0f, -0.5f);
D3DXVec3Normalize( (D3DXVECTOR3*)&light.Direction;, &vecDir; );

light.Specular.r = 1.0f;
light.Specular.g = 1.0f;
light.Specular.b = 1.0f;
light.Specular.a = 1.0f;

light.Range = 1000;
light.Falloff = 0;
light.Attenuation0 = 1;
light.Attenuation1 = 0;
light.Attenuation2 = 0;
m_pd3dDevice->SetLight( 0, &light; );
m_pd3dDevice->LightEnable( 0, TRUE );
m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, TRUE );

mtrl.Specular.r = 1.0f;
mtrl.Specular.g = 1.0f;
mtrl.Specular.b = 1.0f;
mtrl.Specular.a = 1.0f;
mtrl.Power = 20;
m_pd3dDevice->SetMaterial( &mtrl; );
m_pd3dDevice->SetRenderState(D3DRS_SPECULARMATERIALSOURCE, D3DMCS_MATERIAL);

According to the equation, the resulting color for the object vertices is a combination of the material color and the light color.

These two images show the material color, which is gray, and the light color, which is white.

The resulting specular highlight is shown below.

Combining the specular highlight with the ambient and diffuse lighting produces the following image. With all three types of lighting applied, this more clearly resembles a realistic object.

Specular lighting is more intensive to calculate than diffuse lighting. It is typically used to provide visual clues about the surface material. The specular highlight varies in size and color with the material of the surface.