Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lighting.

Similar presentations


Presentation on theme: "Lighting."— Presentation transcript:

1 Lighting

2 Mathematics of Lighting

3 light.c #include <GL/glut.h> void init(void) { GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 50.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); }

4 void display(void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidSphere (1.0, 20, 16); glFlush (); }

5 void reshape (int w, int h) { glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-1.5, 1.5, -1.5*(GLfloat)h/(GLfloat)w, 1.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0); else glOrtho (-1.5*(GLfloat)w/(GLfloat)h, 1.5*(GLfloat)w/(GLfloat)h, -1.5, 1.5, -10.0, 10.0); glMatrixMode(GL_MODELVIEW); }

6 int main(int argc, char** argv) { glutInit(&argc, argv); glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize (500, 500); glutInitWindowPosition (100, 100); glutCreateWindow (argv[0]); init (); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMainLoop(); return 0; }

7

8 The total color from all lighting
color_from_light0 + color_from_light1 + color_from_light2 + ... + material_ambient * lightmodel_ambient + material_emission

9 Global Ambient Light GLfloat lmodel_ambient[ ]= { 0.2, 0.2, 0.2, 1.0 }; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); In this example, the values used for lmodel_ambient are the default values for GL_LIGHT_MODEL_AMBIENT. Since these numbers yield a small amount of white ambient light, even if you don't add a specific light source to your scene, you can still see the objects in the scene. GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat);

10 Material emission By specifying an RGBA color for GL_EMISSION, you can make an object appear to be giving off light of that color. you'll probably use this feature mostly to simulate lamps and other light sources in a scene. GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0}; glMaterialfv(GL_FRONT, GL_EMISSION, mat_emission);

11 Enabling Lighting With OpenGL, you need to explicitly enable (or disable) lighting. If lighting isn't enabled, the current color is simply mapped onto the current vertex glEnable(GL_LIGHTING); glDisable(GL_LIGHTING); You also need to explicitly enable each light source that you define glEnable(GL_LIGHT0); GL_LIGHT0, GL_LIGHT1, ... , or GL_LIGHT7

12 The total color from a single light
color = attenuation factor * spotlight effect * ( diffuse * material_diffuse * light_diffuse + specular * material_specular * light_specular + material_ambient * light_ambient )

13 Directional and Positional lights
directional light source; infinite location is that the rays of light can be considered parallel by the time they reach an object. An example of a real-world directional light source is the sun. positional light source, since its exact position within the scene determines the effect it has on a scene and, specifically, the direction from which the light rays come.

14 GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position); you supply a vector of four values (x, y, z, w) for the GL_POSITION parameter. If the last value, w, is zero, the corresponding light source is a directional one, and the (x, y, z) values describe its direction. This direction is transformed by the modelview matrix. By default, GL_POSITION is (0, 0, 1, 0), which defines a directional light that points along the negative z-axis. If the w value is nonzero, the light is positional, and the (x, y, z) values specify the location of the light. Remember that the colors across the face of a smooth-shaded polygon are determined by the colors calculated for the vertices. Because of this, you probably want to avoid using large polygons with local lights. break up the large polygon into smaller ones.

15 attenuation factor where
d = distance between the light's position and the vertex  kc = GL_CONSTANT_ATTENUATION  kl = GL_LINEAR_ATTENUATION  kq = GL_QUADRATIC_ATTENUATION If the light is a directional one, the attenuation factor is 1. glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0); glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0); glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5);

16 Spotlight Effect The spotlight effect evaluates to one of three possible values: =1 if the light isn't a spotlight (GL_SPOT_CUTOFF is 180.0). =0 if the light is a spotlight but the vertex lies outside the cone of illumination produced by the spotlight. v dot d = cos(a) < cos(t) =(max {v dot d, 0 } )GL_SPOT_EXPONENT where v = (vx, vy, vz) is the unit vector that points from the spotlight (GL_POSITION) to the vertex. d = (dx, dy, dz) is the spotlight's direction (GL_SPOT_DIRECTION) The dot product of the two vectors v and d varies as the cosine of the angle between them; hence, objects directly in line get maximum illumination, and objects off the axis have their illumination drop as the cosine of the angle.

17 Spotlight By default, the spotlight feature is disabled because the GL_SPOT_CUTOFF parameter is This value means that light is emitted in all directions The value for GL_SPOT_CUTOFF is restricted to being within the range [0.0,90.0] (unless it has the special value 180.0). glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0); You also need to specify a spotlight's direction, which determines the axis of the cone of light: GLfloat spot_direction[] = { -1.0, -1.0, 0.0 }; glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION, spot_direction); By default, the direction is (0.0, 0.0, -1.0), so if you don't explicitly set the value of GL_SPOT_DIRECTION, the light points down the negative z-axis. glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);

18 Ambient Lighting R = light.r * material.r G = light.g * material.g
B = light.b * material.b (light.r is the red value of the GL_AMBIENT color of the light source, etc.)

19 Diffuse Lighting R = diffuse_intensity * light.red * material.red
diffuse_intensity = max(normal dot light_dir, 0) = normal.x * light_dir.x + normal.y * light_dir.y + normal.z * light_dir.z R = diffuse_intensity * light.red * material.red G = diffuse_intensity * light.green * material.green B = diffuse_intensity * light.blue * material.blue (light.red is the red value of the GL_DIFFUSE color of the light source, etc.)

20 Specular Lighting R = specular_intensity * light.r * material.r
s_vector (half)= normalize( light_dir + view_dir ) specular_intensity = (s_vector dot normal)shininess× 128 R = specular_intensity * light.r * material.r G = specular_intensity * light.g * material.g B = specular_intensity * light.b * material.b (light.r is the red value of the GL_SPECULAR color of the light source, etc.)

21 Color and Light Distribution for a Red Laser Light Source
You could interpret this table as saying that the red laser light in some scenes has a very high specular component, a small diffuse component, and a very small ambient component. Wherever it shines, you are probably going to see a reddish spot.

22 void glLight{if}[v](GLenum light, GLenum pname, TYPEparam);
Default Values for pname Parameter of glLight*() Parameter NameDefault ValueMeaning GL_AMBIENT (0.0, 0.0, 0.0, 1.0) ambient RGBA intensity GL_DIFFUSE (1.0, 1.0, 1.0, 1.0) diffuse RGBA intensity GL_SPECULAR (1.0, 1.0, 1.0, 1.0) specular RGBA intensity GL_POSITION (0.0, 0.0, 1.0, 0.0) (x, y, z, w) position GL_SPOT_DIRECTION (0.0, 0.0, -1.0) (x, y, z) direction GL_SPOT_EXPONENT 0.0 spotlight exponent GL_SPOT_CUTOFF spotlight cutoff angle GL_CONSTANT_ATTENUATION 1.0 constant attenuation GL_LINEAR_ATTENUATION 0.0 linear attenuation GL_QUADRATIC_ATTENUATION 0.0 quadratic attenuation The default values listed for GL_DIFFUSE and GL_SPECULAR apply only to GL_LIGHT0. For other lights, the default value is (0.0, 0.0, 0.0, 1.0) for both GL_DIFFUSE and GL_SPECULAR.

23 GLfloat light1_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
GLfloat light1_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light1_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light1_position[] = { -2.0, 2.0, 1.0, 1.0 }; GLfloat spot_direction[] = { -1.0, -1.0, 0.0 }; glLightfv(GL_LIGHT1, GL_AMBIENT, light1_ambient); glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse); glLightfv(GL_LIGHT1, GL_SPECULAR, light1_specular); glLightfv(GL_LIGHT1, GL_POSITION, light1_position); glLightf(GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.5); glLightf(GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.5); glLightf(GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.2); glLightf(GL_LIGHT1, GL_SPOT_CUTOFF, 45.0); glLightfv(GL_LIGHT1, GL_SPOT_DIRECTION, spot_direction); glLightf(GL_LIGHT1, GL_SPOT_EXPONENT, 2.0); glEnable(GL_LIGHT1);

24 glMaterial{if}[v](GLenum face, GLenum pname, TYPEparam);
Default Values for pname Parameter of glMaterial*() Parameter Name Default Value Meaning GL_AMBIENT (0.2, 0.2, 0.2, 1.0) ambient color GL_DIFFUSE (0.8, 0.8, 0.8, 1.0) diffuse color GL_AMBIENT_AND_DIFFUSE ambient and diffuse color GL_SPECULAR (0.0, 0.0, 0.0, 1.0) specular color GL_SHININESS 0.0 specular exponent GL_EMISSION (0.0, 0.0, 0.0, 1.0) emissive color

25 GLfloat no_mat[ ] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_diffuse[ ] = { 0.1, 0.5, 0.8, 1.0 }; GLfloat no_shininess[ ] = { 0.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat); glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, no_mat);

26 Local or Infinite Viewpoint
Specular Lighting: s_vector (half)= normalize( light_dir + view_dir ) specular_intensity = (s_vector dot normal)shininess× 128 R = specular_intensity * light.r * material.r With an infinite viewpoint, the direction between it and any vertex in the scene remains constant (i.e; view_dir =constant = (0, 0, 1) ) A local viewpoint tends to yield more realistic results, but since the direction has to be calculated for each vertex, overall performance is decreased with a local viewpoint. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

27 Two-sided Lighting Lighting calculations are performed for all polygons, whether they're front-facing or back-facing. Since you usually set up lighting conditions with the front-facing polygons in mind, however, the back-facing ones typically aren't correctly illuminated. e.g., If a sphere was going to be cut away so that its inside surface would be visible glLightModeli(LIGHT_MODEL_TWO_SIDE, GL_TRUE); OpenGL reverses the surface normals As a result, all polygons are illumnated correctly. To turn two-sided lighting off, pass in GL_FALSE as the argument in the preceding call.

28 scene.c void init (void){
GLfloat light_ambient[ ] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[ ] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[ ] = { 1.0, 1.0, 1.0, 1.0 }; /* light_position is NOT default value */ GLfloat light_position[ ] = { 1.0, 1.0, 1.0, 0.0 }; glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv (GL_LIGHT0, GL_POSITION, light_position); glEnable (GL_LIGHTING); glEnable (GL_LIGHT0); glEnable(GL_DEPTH_TEST); } void display (void){ glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glRotatef (20.0, 1.0, 0.0, 0.0); glTranslatef (-0.75, 0.5, 0.0); glRotatef (90.0, 1.0, 0.0, 0.0); glutSolidTorus (0.275, 0.85, 15, 15); glPopMatrix (); …….

29 material.c void init(void) {
GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat position[] = { 0.0, 3.0, 2.0, 0.0 }; GLfloat lmodel_ambient[] = { 0.4, 0.4, 0.4, 1.0 }; GLfloat local_view[] = { 0.0 }; glClearColor(0.0, 0.1, 0.1, 0.0); glEnable(GL_DEPTH_TEST); glShadeModel(GL_SMOOTH); glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT0, GL_POSITION, position); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); }

30 * Draw twelve spheres in 3 rows with 4 columns.
* The spheres in the first row have materials with no ambient reflection. * The second row has materials with significant ambient reflection. * The third row has materials with colored ambient reflection. * * The first column has materials with blue, diffuse reflection only. * The second column has blue diffuse reflection, as well as specular * reflection with a low shininess exponent. * The third column has blue diffuse reflection, as well as specular * reflection with a high shininess exponent (a more concentrated highlight). * The fourth column has materials which also include an emissive component.

31 GLfloat no_mat[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat mat_ambient[] = { 0.7, 0.7, 0.7, 1.0 }; GLfloat mat_ambient_color[] = { 0.8, 0.8, 0.2, 1.0 }; GLfloat mat_diffuse[] = { 0.1, 0.5, 0.8, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat no_shininess[] = { 0.0 }; GLfloat low_shininess[] = { 5.0 }; GLfloat high_shininess[] = { }; GLfloat mat_emission[] = {0.3, 0.2, 0.2, 0.0}; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* draw sphere in first row, first column * diffuse reflection only; no ambient or specular */ glPushMatrix(); glTranslatef (-3.75, 3.0, 0.0); glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, no_mat); glMaterialfv(GL_FRONT, GL_SHININESS, no_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, no_mat); glutSolidSphere(1.0, 16, 16); glPopMatrix();

32 /* draw sphere in first row, second column
* diffuse and specular reflection; low shininess; no ambient */ glPushMatrix(); glTranslatef (-1.25, 3.0, 0.0); glMaterialfv(GL_FRONT, GL_AMBIENT, no_mat); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess); glMaterialfv(GL_FRONT, GL_EMISSION, no_mat); glutSolidSphere(1.0, 16, 16); glPopMatrix(); As you can see, glMaterialfv() is called repeatedly to set the desired material property for each sphere.

33 Color Tracking With color tracking, you can tell OpenGL to set material properties by only calling glColor. To enable color tracking, call glEnable with the GL_COLOR_MATERIAL parameter Then the function glColorMaterial specifies the material parameters that follow the values set by glColor. For example, to set the ambient and diffuse properties of the fronts of polygons to track the colors set by glColor, call glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); // Enable color tracking glEnable(GL_COLOR_MATERIAL); // Front material ambient and diffuse colors track glColor ... glcolor3f(0.75f, 0.75f, 0.75f); glBegin(GL_TRIANGLES); glVertex3f(-15.0f,0.0f,30.0f); glVertex3f(0.0f, 15.0f, 30.0f); glVertex3f(0.0f, 0.0f, -56.0f); glEnd();

34 color tracking minimizes performance costs associated with changing material properties is to use
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, GL_BACK, or GL_FRONT_AND_BACK (the default). The mode parameter can be GL_AMBIENT, GL_DIFFUSE, GL_AMBIENT_AND_DIFFUSE (the default), GL_SPECULAR, or GL_EMISSION. Note that glColorMaterial() specifies two independent values: the first specifies which face or faces are updated, and the second specifies which material property or properties of those faces are updated. You should use glColorMaterial() whenever you need to change a single material parameter for most vertices in your scene.

35 Ambient.cpp (ch5) void SetupRC( ){ // Light values
// Bright white light GLfloat ambientLight[] = { 1.0f, 1.0f, 1.0f, 1.0f }; glEnable(GL_DEPTH_TEST); // Hidden surface removal glEnable(GL_CULL_FACE); // Do not calculate inside of jet glFrontFace(GL_CCW); // Counterclockwise polygons face out // Lighting stuff glEnable(GL_LIGHTING); // Enable lighting // Set light model to use ambient light specified by ambientLight[] glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight); glEnable(GL_COLOR_MATERIAL); // Enable material color tracking // Front material ambient and diffuse colors track glColor glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE); // Nice light blue background glClearColor(0.0f, 0.0f, 05.f,1.0f);}

36 void RenderScene(void)
{ // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Save the matrix state glPushMatrix(); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); // Nose Cone ///////////////////////////// // Bright Green glColor3ub(0, 255, 0); glBegin(GL_TRIANGLES); glVertex3f(0.0f, 0.0f, 60.0f); glVertex3f(-15.0f, 0.0f, 30.0f); glVertex3f(15.0f,0.0f,30.0f); ………..

37 GLfloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };
The final output is not much different from the image before we had lighting. However, if we reduce the ambient light by half, we get the image shown in the following figure. To reduce it by half, we set the ambient light RGBA values to the following: GLfloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f };

38 colormat.c GLfloat diffuseMaterial[4] = { 0.5, 0.5, 0.5, 1.0 };
void init(void) { GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; glClearColor (0.0, 0.0, 0.0, 0.0); glShadeModel (GL_SMOOTH); glEnable(GL_DEPTH_TEST); glMaterialfv(GL_FRONT, GL_DIFFUSE, diffuseMaterial); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialf(GL_FRONT, GL_SHININESS, 25.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glColorMaterial(GL_FRONT, GL_DIFFUSE); glEnable(GL_COLOR_MATERIAL); } void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glutSolidSphere(1.0, 20, 16); glFlush ();

39 void mouse(int button, int state, int x, int y)
{ switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { diffuseMaterial[0] += 0.1; if (diffuseMaterial[0] > 1.0) diffuseMaterial[0] = 0.0; glColor4fv(diffuseMaterial); glutPostRedisplay(); } break;

40 movelight.c void display(void) {
GLfloat position[ ] = { 0.0, 0.0, 1.5, 1.0 }; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glRotated ((GLdouble) spin, 1.0, 0.0, 0.0); glLightfv (GL_LIGHT0, GL_POSITION, position); glTranslated (0.0, 0.0, 1.5); glDisable (GL_LIGHTING); glColor3f (0.0, 1.0, 1.0); glutWireCube (0.1); glEnable (GL_LIGHTING); glPopMatrix (); glutSolidTorus (0.275, 0.85, 8, 15); glFlush (); }

41 LitJet.cpp (ch5) void SetupRC() { // Light values and coordinates
GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f }; GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f }; glEnable(GL_DEPTH_TEST); // Hidden surface removal glFrontFace(GL_CCW); // Counterclockwise polygons face out glEnable(GL_CULL_FACE); // Do not calculate inside of jet // Enable lighting glEnable(GL_LIGHTING); // Set up and enable light 0 glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight); glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight); glEnable(GL_LIGHT0); // Enable color tracking glEnable(GL_COLOR_MATERIAL); // Set material properties to follow glColor values glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Light blue background glClearColor(0.0f, 0.0f, 1.0f, 1.0f ); // Rescale normals to unit length glEnable(GL_NORMALIZE);}

42 void RenderScene(void) {
M3DVector3f vNormal; // Storeage for calculated surface normal { M3DVector3f vPoints[3] = {{ 15.0f, 0.0f, 30.0f}, { 0.0f, 15.0f, 30.0f}, { 0.0f, 0.0f, 60.0f}}; // Calculate the normal for the plane m3dFindNormal(vNormal, vPoints[0], vPoints[1], vPoints[2]); glNormal3fv(vNormal); glVertex3fv(vPoints[0]); glVertex3fv(vPoints[1]); glVertex3fv(vPoints[2]); }

43 The most obvious way to improve the performance of this code is to calculate all the normal vectors ahead of time and store them for use in the RenderScene function. Display lists and vertex arrays provide a means of storing calculated values not only for the normal vectors, but for the polygon data as well. Remember, these examples are meant to demonstrate the concepts. They are not necessarily the most efficient code possible.

44 ShinyJet.cpp (ch5) Adding Specular Highlights

45 Specular lighting and material properties add needed gloss to the surface of your objects.
This shininess has a brightening effect on an object’s color and can produce specular highlights when the angle of incident light is sharp in relation to the viewer. // Light values and coordinates GLfloat ambientLight[] = { 0.3f, 0.3f, 0.3f, 1.0f }; GLfloat diffuseLight[] = { 0.7f, 0.7f, 0.7f, 1.0f }; GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f}; ... // Enable lighting glEnable(GL_LIGHTING); // Set up and enable light 0 glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight); glLightfv(GL_LIGHT0,GL_DIFFUSE,diffuseLight); glLightfv(GL_LIGHT0,GL_SPECULAR,specular); glEnable(GL_LIGHT0); If this were the only change you made to LITJET, you wouldn’t see any difference in the jet’s appearance. We haven’t yet defined any specular reflectance properties for the material properties.

46 Adding specular reflectance to material properties
// Light values and coordinates GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f }; ... // Enable color tracking glEnable(GL_COLOR_MATERIAL); // Set material properties to follow glColor values glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // All materials hereafter have full specular reflectivity // with a high shine glMaterialfv(GL_FRONT, GL_SPECULAR,specref); glMateriali(GL_FRONT,GL_SHININESS,128); //The range of this parameter is 1–128 for all conformant implementations of OpenGL.

47 Spot.cpp (ch5) This program places a blue sphere in the center of the window. It also creates a spotlight that you can move vertically with the up- and down-arrow keys and horizontally with the leftand right-arrow keys. As the spotlight moves over the surface of the sphere, a specular highlight follows it on the surface. The pop-up menu contains items to set flat and smooth shading and to produce a sphere for low, medium, and high approximation. Surface approximation means to break the mesh of a curved surface into a finer mesh of polygons (more vertices). A drawback of vertex lighting (not necessarily OpenGL!). By lighting the vertices and then interpolating between them, we get a crude approximation of lighting.

48 GLfloat lightPos[] = { 0.0f, 0.0f, 75.0f, 1.0f };
GLfloat specular[] = { 1.0f, 1.0f, 1.0f, 1.0f}; GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f }; GLfloat ambientLight[] = { 0.5f, 0.5f, 0.5f, 1.0f}; GLfloat spotDir[] = { 0.0f, 0.0f, -1.0f }; void SetupRC() { glEnable(GL_DEPTH_TEST); // Hidden surface removal glFrontFace(GL_CCW); // Counterclockwise polygons face out glEnable(GL_CULL_FACE); // Do not try to display the back sides // Enable lighting glEnable(GL_LIGHTING); // Set up and enable light 0 // Supply a slight ambient light so the objects can be seen glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight); // The light is composed of just diffuse and specular components glLightfv(GL_LIGHT0,GL_DIFFUSE,ambientLight); glLightfv(GL_LIGHT0,GL_SPECULAR,specular); glLightfv(GL_LIGHT0,GL_POSITION,lightPos); // Specific spot effects. This line what makes a positional light source into a spotlight: glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,60.0f); // Enable this light in particular glEnable(GL_LIGHT0);

49 CAN YOU SEE THE LIGHT? No. Lights in OpenGL cannot be seen by themselves. Spotlights do not create cones of light, and beams of sunlight streaming in a window do not create beams or shafts of light. To create these effects in OpenGL, you will actually have to draw geometry, such as real cones or shafts, often using the blending operations covered later. Lights also go through objects and do not cast shadows. One technique for drawing shadows will be presented soon.

50 void RenderScene(void) {
if(iShade == MODE_FLAT) glShadeModel(GL_FLAT); else // iShade = MODE_SMOOTH; glShadeModel(GL_SMOOTH); // Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // First place the light // Save the coordinate transformation glPushMatrix(); // Rotate coordinate system glRotatef(yRot, 0.0f, 1.0f, 0.0f); glRotatef(xRot, 1.0f, 0.0f, 0.0f); // Specify new position and direction in rotated coords glLightfv(GL_LIGHT0,GL_POSITION,lightPos); glLightfv(GL_LIGHT0,GL_SPOT_DIRECTION,spotDir);

51 // Draw a red cone to enclose the light source
glColor3ub(255,0,0); // Translate origin to move the cone out to where the light // is positioned. glTranslatef(lightPos[0],lightPos[1],lightPos[2]); glutSolidCone(4.0f,6.0f,15,15); // Draw a smaller displaced sphere to denote the light bulb // Save the lighting state variables glPushAttrib(GL_LIGHTING_BIT); // Turn off lighting and specify a bright yellow sphere glDisable(GL_LIGHTING); glColor3ub(255,255,0); glutSolidSphere(3.0f, 15, 15); // Restore lighting state variables glPopAttrib(); // Restore coordinate transformations glPopMatrix();

52 // Set material color and draw a sphere in the middle
glColor3ub(0, 0, 255); if(iTess == MODE_VERYLOW) glutSolidSphere(30.0f, 7, 7); else if(iTess == MODE_MEDIUM) glutSolidSphere(30.0f, 15, 15); else // iTess = MODE_MEDIUM; glutSolidSphere(30.0f, 50, 50); // Display the results glutSwapBuffers(); }

53 Shadows

54 Squish Code We need to flatten the modelview matrix so that any and all objects drawn into it are now in this flattened two-dimensional world. No matter how the object is oriented, it is projected (squished) into the plane in which the shadow lies. The next two considerations are the distance and direction of the light source. The function m3dMakePlanarShadowMatrix from the math3d library takes the plane equation of the plane in which you want the shadow to appear (three points that cannot be along the same straight line can be fed to m3dGetPlaneEquation to get the equation of the plane), and the position of the light source, and returns a transformation matrix that this function constructs. This function builds a transformation matrix. If you multiply this matrix by the current modelview matrix, all further drawing is flattened into this plane.

55 Shadow.cpp (ch5) GLfloat lightPos[] = { -75.0f, 150.0f, -50.0f, 0.0f }; // Transformation matrix to project shadow M3DMatrix44f shadowMat; void SetupRC() { // Any three points on the ground (counterclockwise order) M3DVector3f points[3] = {{ -30.0f, f, -20.0f }, { -30.0f, f, 20.0f }, { 40.0f, f, 20.0f }}; glEnable(GL_DEPTH_TEST); // Hidden surface removal glFrontFace(GL_CCW); // Counterclockwise polygons face out glEnable(GL_CULL_FACE); // Do not calculate inside of jet glEnable(GL_LIGHTING); ……. // Get the plane equation from three points on the ground M3DVector4f vPlaneEquation; m3dGetPlaneEquation(vPlaneEquation, points[0], points[1], points[2]); // Calculate projection matrix to draw shadow on the ground m3dMakePlanarShadowMatrix(shadowMat, vPlaneEquation, lightPos); . . .}

56 void RenderScene(void) {
// Clear the window with current clearing color glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Draw the ground; we do manual shading to a darker green // in the background to give the illusion of depth glBegin(GL_QUADS); glColor3ub(0,32,0); glVertex3f(400.0f, f, f); glVertex3f(-400.0f, f, f); glColor3ub(0,255,0); glVertex3f(-400.0f, f, 200.0f); glVertex3f(400.0f, f, 200.0f); glEnd(); // Save the matrix state and do the rotations glPushMatrix(); // Draw jet at new orientation; put light in correct position // before rotating the jet glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0,GL_POSITION,lightPos); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f);

57 DrawJet(FALSE); // Restore original matrix state glPopMatrix(); // Get ready to draw the shadow and the ground // First disable lighting and save the projection state glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); glPushMatrix(); // Multiply by shadow projection matrix glMultMatrixf((GLfloat *)shadowMat); // Now rotate the jet around in the new flattened space glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); // Pass true to indicate drawing shadow DrawJet(TRUE); // Restore the projection to normal

58 // Draw the light source
glPushMatrix(); glTranslatef(lightPos[0],lightPos[1], lightPos[2]); glColor3ub(255,255,0); glutSolidSphere(5.0f,10,10); glPopMatrix(); // Restore lighting state variables glEnable(GL_DEPTH_TEST); // Display the results glutSwapBuffers(); }

59 SphereWorld.cpp (ch5)


Download ppt "Lighting."

Similar presentations


Ads by Google