OpenGL lighting determines the appearance of objects by simulating (roughly) the behavior of light reflecting off of the objects. The lighting calculation is the combination of several different components.
For 'something' being rendered, the color from lighting is:
final_color = color_from_light0 + color_from_light1 + ... + color_from_global_ambient + material_emission color_from_lightN = material_ambient_color * ambient_light_from_N + material_diffuse_color * diffuse_light_from_N + material_specular_color * specular_light_from_N ambient_light_from_N = light_N_ambient_component diffuse_light_from_N = dotproduct( surface_normal, light_N_direction ) * light_N_diffuse_component specular_light_from_N = specularFunction(surface_normal, light_N_direction, eye_direction, shininess) * light_N_specular_component
The steps to use lighting in OpenGL are:
Enable lighting | glEnable(GL_LIGHTING); |
Define light(s) | GLfloat white[4] = { 1, 1, 1, 1 }; GLfloat dimwhite[4] = { 0.1, 0.1, 0.1, 0.1 }; GLfloat lightPos[4] = {0, 1, 0, 0}; glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_DIFFUSE, white); glLightfv(GL_LIGHT0, GL_AMBIENT, dimwhite); glLightfv(GL_LIGHT0, GL_POSITION, lightPos); |
Define a material | GLfloat blue[4] = { 0, .4, 1, 1 }; GLfloat white[4] = { 1, 1, 1, 1 }; glMaterialfv(GL_FRONT, GL_DIFFUSE, blue); glMaterialfv(GL_FRONT, GL_AMBIENT, blue); glMaterialfv(GL_FRONT, GL_SPECULAR, white); glMaterialf(GL_FRONT, GL_SHININESS, 60.0); |
Assign normal(s) | glNormal3f(0.0, 1.0, 0.0); glVertex3f(x,y,z); |
GLUT objects and GLU quadrics have their normals provided automatically.
Last week's example program waves-lit.c had a bug. The correct way to turn off specularity in a material is to set the specular color to black (all zeroes).
if (specularity) { glMaterialfv(GL_FRONT, GL_SPECULAR, white); glMaterialf(GL_FRONT, GL_SHININESS, 60.0); } else { glMaterialfv(GL_FRONT, GL_SPECULAR, black); glMaterialf(GL_FRONT, GL_SHININESS, 0.0); }
Corrected program: waves-lit.c