Lighting Mathematics of Lighting light c include GLglut

  • Slides: 59
Download presentation
Lighting

Lighting

Mathematics of Lighting

Mathematics of Lighting

light. c #include <GL/glut. h> void init(void) { GLfloat mat_specular[] = { 1. 0,

light. c #include <GL/glut. h> void init(void) { GLfloat mat_specular[] = { 1. 0, 1. 0 }; GLfloat mat_shininess[] = { 50. 0 }; GLfloat light_position[] = { 1. 0, 0. 0 }; gl. Clear. Color (0. 0, 0. 0); gl. Shade. Model (GL_SMOOTH); gl. Materialfv(GL_FRONT, GL_SPECULAR, mat_specular); gl. Materialfv(GL_FRONT, GL_SHININESS, mat_shininess); gl. Lightfv(GL_LIGHT 0, GL_POSITION, light_position); gl. Enable(GL_LIGHTING); gl. Enable(GL_LIGHT 0); gl. Enable(GL_DEPTH_TEST); }

void display(void) { gl. Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glut. Solid. Sphere (1. 0, 20,

void display(void) { gl. Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glut. Solid. Sphere (1. 0, 20, 16); gl. Flush (); }

void reshape (int w, int h) { gl. Viewport (0, 0, (GLsizei) w, (GLsizei)

void reshape (int w, int h) { gl. Viewport (0, 0, (GLsizei) w, (GLsizei) h); gl. Matrix. Mode (GL_PROJECTION); gl. Load. Identity(); if (w <= h) gl. Ortho (-1. 5, -1. 5*(GLfloat)h/(GLfloat)w, -10. 0, 10. 0); else gl. Ortho (-1. 5*(GLfloat)w/(GLfloat)h, -1. 5, -10. 0, 10. 0); gl. Matrix. Mode(GL_MODELVIEW); gl. Load. Identity(); }

int main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_SINGLE

int main(int argc, char** argv) { glut. Init(&argc, argv); glut. Init. Display. Mode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); glut. Init. Window. Size (500, 500); glut. Init. Window. Position (100, 100); glut. Create. Window (argv[0]); init (); glut. Display. Func(display); glut. Reshape. Func(reshape); glut. Main. Loop(); return 0; }

The total color from all lighting color = color_from_light 0 + color_from_light 1 +

The total color from all lighting color = color_from_light 0 + color_from_light 1 + color_from_light 2 +. . . + material_ambient * lightmodel_ambient + material_emission

Global Ambient Light • GLfloat lmodel_ambient[ ]= { 0. 2, 1. 0 }; gl.

Global Ambient Light • GLfloat lmodel_ambient[ ]= { 0. 2, 1. 0 }; gl. Light. Modelfv(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, 1. 0 }; gl. Materialfv(GL_FRONT, GL_AMBIENT, no_mat);

Material emission • By specifying an RGBA color for GL_EMISSION, you can make an

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. 0}; gl. Materialfv(GL_FRONT, GL_EMISSION, mat_emission);

Enabling Lighting • With Open. GL, you need to explicitly enable (or disable) lighting.

Enabling Lighting • With Open. GL, you need to explicitly enable (or disable) lighting. If lighting isn't enabled, the current color is simply mapped onto the current vertex – gl. Enable(GL_LIGHTING); – gl. Disable(GL_LIGHTING); • You also need to explicitly enable each light source that you define – gl. Enable(GL_LIGHT 0); • GL_LIGHT 0, GL_LIGHT 1, . . . , or GL_LIGHT 7

The total color from a single light color = attenuation factor * spotlight effect

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 )

Directional and Positional lights • directional light source; – infinite location is that the

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.

GLfloat light_position[] = { 1. 0, 0. 0 }; gl. Lightfv(GL_LIGHT 0, GL_POSITION, light_position);

GLfloat light_position[] = { 1. 0, 0. 0 }; gl. Lightfv(GL_LIGHT 0, 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.

attenuation factor where d = distance between the light's position and the vertex kc

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. gl. Lightf(GL_LIGHT 0, GL_CONSTANT_ATTENUATION, 2. 0); gl. Lightf(GL_LIGHT 0, GL_LINEAR_ATTENUATION, 1. 0); gl. Lightf(GL_LIGHT 0, GL_QUADRATIC_ATTENUATION, 0. 5);

Spotlight Effect • The spotlight effect evaluates to one of three possible values: –

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.

Spotlight • By default, the spotlight feature is disabled because the GL_SPOT_CUTOFF parameter is

Spotlight • By default, the spotlight feature is disabled because the GL_SPOT_CUTOFF parameter is 180. 0. – 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). gl. Lightf(GL_LIGHT 0, 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, 0. 0 }; gl. Lightfv(GL_LIGHT 0, GL_SPOT_DIRECTION, spot_direction); By default, the direction is (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. gl. Lightf(GL_LIGHT 0, GL_SPOT_EXPONENT, 2. 0);

Ambient Lighting • R = light. r * material. r • G = light.

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. )

Diffuse Lighting diffuse_intensity = max(normal dot light_dir, 0) = normal. x * light_dir. x

Diffuse Lighting 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. )

Specular Lighting s_vector (half)= normalize( light_dir + view_dir ) specular_intensity = (s_vector dot normal)shininess×

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 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. )

 • Color and Light Distribution for a Red Laser Light Source • You

• 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.

void gl. Light{if}[v](GLenum light, GLenum pname, TYPEparam); • Default Values for pname Parameter of

void gl. Light{if}[v](GLenum light, GLenum pname, TYPEparam); • Default Values for pname Parameter of gl. Light*() Parameter Name. Default Value. Meaning GL_AMBIENT (0. 0, 1. 0) ambient RGBA intensity GL_DIFFUSE (1. 0, 1. 0) diffuse RGBA intensity GL_SPECULAR (1. 0, 1. 0) specular RGBA intensity GL_POSITION (0. 0, 1. 0, 0. 0) (x, y, z, w) position GL_SPOT_DIRECTION (0. 0, -1. 0) (x, y, z) direction GL_SPOT_EXPONENT 0. 0 spotlight exponent GL_SPOT_CUTOFF 180. 0 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_LIGHT 0. For other lights, the default value is (0. 0, 1. 0) for both GL_DIFFUSE and GL_SPECULAR.

GLfloat light 1_ambient[] = { 0. 2, 1. 0 }; GLfloat light 1_diffuse[] =

GLfloat light 1_ambient[] = { 0. 2, 1. 0 }; GLfloat light 1_diffuse[] = { 1. 0, 1. 0 }; GLfloat light 1_specular[] = { 1. 0, 1. 0 }; GLfloat light 1_position[] = { -2. 0, 1. 0 }; GLfloat spot_direction[] = { -1. 0, 0. 0 }; gl. Lightfv(GL_LIGHT 1, GL_AMBIENT, light 1_ambient); gl. Lightfv(GL_LIGHT 1, GL_DIFFUSE, light 1_diffuse); gl. Lightfv(GL_LIGHT 1, GL_SPECULAR, light 1_specular); gl. Lightfv(GL_LIGHT 1, GL_POSITION, light 1_position); gl. Lightf(GL_LIGHT 1, GL_CONSTANT_ATTENUATION, 1. 5); gl. Lightf(GL_LIGHT 1, GL_LINEAR_ATTENUATION, 0. 5); gl. Lightf(GL_LIGHT 1, GL_QUADRATIC_ATTENUATION, 0. 2); gl. Lightf(GL_LIGHT 1, GL_SPOT_CUTOFF, 45. 0); gl. Lightfv(GL_LIGHT 1, GL_SPOT_DIRECTION, spot_direction); gl. Lightf(GL_LIGHT 1, GL_SPOT_EXPONENT, 2. 0); gl. Enable(GL_LIGHT 1);

gl. Material{if}[v](GLenum face, GLenum pname, TYPEparam); • Default Values for pname Parameter of gl.

gl. Material{if}[v](GLenum face, GLenum pname, TYPEparam); • Default Values for pname Parameter of gl. Material*() Parameter Name Default Value Meaning GL_AMBIENT (0. 2, 1. 0) ambient color GL_DIFFUSE (0. 8, 1. 0) diffuse color GL_AMBIENT_AND_DIFFUSE ambient and diffuse color GL_SPECULAR (0. 0, 1. 0) specular color GL_SHININESS 0. 0 specular exponent GL_EMISSION (0. 0, 1. 0) emissive color

GLfloat no_mat[ ] = { 0. 0, 1. 0 }; GLfloat mat_diffuse[ ] =

GLfloat no_mat[ ] = { 0. 0, 1. 0 }; GLfloat mat_diffuse[ ] = { 0. 1, 0. 5, 0. 8, 1. 0 }; GLfloat no_shininess[ ] = { 0. 0 }; gl. Materialfv(GL_FRONT, GL_AMBIENT, no_mat); gl. Materialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); gl. Materialfv(GL_FRONT, GL_SPECULAR, no_mat); gl. Materialfv(GL_FRONT, GL_SHININESS, no_shininess); gl. Materialfv(GL_FRONT, GL_EMISSION, no_mat);

Local or Infinite Viewpoint • Specular Lighting: s_vector (half)= normalize( light_dir + view_dir )

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. • gl. Light. Modeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

Two-sided Lighting • Lighting calculations are performed for all polygons, whether they're front-facing or

Two-sided Lighting • Lighting calculations are performed for all polygons, whether they're front-facing or backfacing. – Since you usually set up lighting conditions with the front-facing polygons in mind, however, the backfacing 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 • gl. Light. Modeli(LIGHT_MODEL_TWO_SIDE, GL_TRUE); – Open. GL 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.

scene. c void init (void){ GLfloat light_ambient[ ] = { 0. 0, 1. 0

scene. c void init (void){ GLfloat light_ambient[ ] = { 0. 0, 1. 0 }; GLfloat light_diffuse[ ] = { 1. 0, 1. 0 }; GLfloat light_specular[ ] = { 1. 0, 1. 0 }; /* light_position is NOT default value */ GLfloat light_position[ ] = { 1. 0, 0. 0 }; gl. Lightfv (GL_LIGHT 0, GL_AMBIENT, light_ambient); gl. Lightfv (GL_LIGHT 0, GL_DIFFUSE, light_diffuse); gl. Lightfv (GL_LIGHT 0, GL_SPECULAR, light_specular); gl. Lightfv (GL_LIGHT 0, GL_POSITION, light_position); gl. Enable (GL_LIGHTING); gl. Enable (GL_LIGHT 0); gl. Enable(GL_DEPTH_TEST); } void display (void){ gl. Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl. Push. Matrix (); gl. Rotatef (20. 0, 1. 0, 0. 0); gl. Push. Matrix (); gl. Translatef (-0. 75, 0. 0); gl. Rotatef (90. 0, 1. 0, 0. 0); glut. Solid. Torus (0. 275, 0. 85, 15); gl. Pop. Matrix (); …….

material. c void init(void) { GLfloat ambient[] = { 0. 0, 1. 0 };

material. c void init(void) { GLfloat ambient[] = { 0. 0, 1. 0 }; GLfloat diffuse[] = { 1. 0, 1. 0 }; GLfloat specular[] = { 1. 0, 1. 0 }; GLfloat position[] = { 0. 0, 3. 0, 2. 0, 0. 0 }; GLfloat lmodel_ambient[] = { 0. 4, 1. 0 }; GLfloat local_view[] = { 0. 0 }; gl. Clear. Color(0. 0, 0. 1, 0. 0); gl. Enable(GL_DEPTH_TEST); gl. Shade. Model(GL_SMOOTH); gl. Lightfv(GL_LIGHT 0, GL_AMBIENT, ambient); gl. Lightfv(GL_LIGHT 0, GL_DIFFUSE, diffuse); gl. Lightfv(GL_LIGHT 0, GL_POSITION, position); gl. Light. Modelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); gl. Light. Modelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); gl. Enable(GL_LIGHTING); gl. Enable(GL_LIGHT 0); }

* * * * * Draw twelve spheres in 3 rows with 4 columns.

* * * * * 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.

GLfloat no_mat[] = { 0. 0, 1. 0 }; GLfloat mat_ambient[] = { 0.

GLfloat no_mat[] = { 0. 0, 1. 0 }; GLfloat mat_ambient[] = { 0. 7, 1. 0 }; GLfloat mat_ambient_color[] = { 0. 8, 0. 2, 1. 0 }; GLfloat mat_diffuse[] = { 0. 1, 0. 5, 0. 8, 1. 0 }; GLfloat mat_specular[] = { 1. 0, 1. 0 }; GLfloat no_shininess[] = { 0. 0 }; GLfloat low_shininess[] = { 5. 0 }; GLfloat high_shininess[] = { 100. 0 }; GLfloat mat_emission[] = {0. 3, 0. 2, 0. 0}; gl. Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* draw sphere in first row, first column * diffuse reflection only; no ambient or specular */ gl. Push. Matrix(); gl. Translatef (-3. 75, 3. 0, 0. 0); gl. Materialfv(GL_FRONT, GL_AMBIENT, no_mat); gl. Materialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); gl. Materialfv(GL_FRONT, GL_SPECULAR, no_mat); gl. Materialfv(GL_FRONT, GL_SHININESS, no_shininess); gl. Materialfv(GL_FRONT, GL_EMISSION, no_mat); glut. Solid. Sphere(1. 0, 16); gl. Pop. Matrix();

/* draw sphere in first row, second column * diffuse and specular reflection; low

/* draw sphere in first row, second column * diffuse and specular reflection; low shininess; no ambient */ gl. Push. Matrix(); gl. Translatef (-1. 25, 3. 0, 0. 0); gl. Materialfv(GL_FRONT, GL_AMBIENT, no_mat); gl. Materialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); gl. Materialfv(GL_FRONT, GL_SPECULAR, mat_specular); gl. Materialfv(GL_FRONT, GL_SHININESS, low_shininess); gl. Materialfv(GL_FRONT, GL_EMISSION, no_mat); glut. Solid. Sphere(1. 0, 16); gl. Pop. Matrix(); • As you can see, gl. Materialfv() is called repeatedly to set the desired material property for each sphere.

Color Tracking • • • With color tracking, you can tell Open. GL to

Color Tracking • • • With color tracking, you can tell Open. GL to set material properties by only calling gl. Color. To enable color tracking, call gl. Enable with the GL_COLOR_MATERIAL parameter Then the function gl. Color. Material specifies the material parameters that follow the values set by gl. Color. – For example, to set the ambient and diffuse properties of the fronts of polygons to track the colors set by gl. Color, call gl. Color. Material(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Enable color tracking gl. Enable(GL_COLOR_MATERIAL); // Front material ambient and diffuse colors track gl. Color. Material(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); . . . glcolor 3 f(0. 75 f, 0. 75 f); gl. Begin(GL_TRIANGLES); gl. Vertex 3 f(-15. 0 f, 0. 0 f, 30. 0 f); gl. Vertex 3 f(0. 0 f, 15. 0 f, 30. 0 f); gl. Vertex 3 f(0. 0 f, -56. 0 f); gl. End();

 • color tracking minimizes performance costs associated with changing material properties is to

• color tracking minimizes performance costs associated with changing material properties is to use – gl. Color. Material(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 gl. Color*()) 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 gl. Color. Material() 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 gl. Color. Material() whenever you need to change a single material parameter for most vertices in your scene.

Ambient. cpp (ch 5) void Setup. RC( ){ // Light values // Bright white

Ambient. cpp (ch 5) void Setup. RC( ){ // Light values // Bright white light GLfloat ambient. Light[] = { 1. 0 f, 1. 0 f }; gl. Enable(GL_DEPTH_TEST); // Hidden surface removal gl. Enable(GL_CULL_FACE); // Do not calculate inside of jet gl. Front. Face(GL_CCW); // Counterclockwise polygons face out // Lighting stuff gl. Enable(GL_LIGHTING); // Enable lighting // Set light model to use ambient light specified by ambient. Light[] gl. Light. Modelfv(GL_LIGHT_MODEL_AMBIENT, ambient. Light); gl. Enable(GL_COLOR_MATERIAL); // Enable material color tracking // Front material ambient and diffuse colors track gl. Color. Material(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Nice light blue background gl. Clear. Color(0. 0 f, 05. f, 1. 0 f); }

void Render. Scene(void) { // Clear the window with current clearing color gl. Clear(GL_COLOR_BUFFER_BIT

void Render. Scene(void) { // Clear the window with current clearing color gl. Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Save the matrix state gl. Push. Matrix(); gl. Rotatef(x. Rot, 1. 0 f, 0. 0 f); gl. Rotatef(y. Rot, 0. 0 f, 1. 0 f, 0. 0 f); // Nose Cone /////////////// // Bright Green gl. Color 3 ub(0, 255, 0); gl. Begin(GL_TRIANGLES); gl. Vertex 3 f(0. 0 f, 60. 0 f); gl. Vertex 3 f(-15. 0 f, 0. 0 f, 30. 0 f); gl. Vertex 3 f(15. 0 f, 0. 0 f, 30. 0 f); ………. .

 • The final output is not much different from the image before we

• 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 ambient. Light[] = { 0. 5 f, 1. 0 f };

colormat. c GLfloat diffuse. Material[4] = { 0. 5, 1. 0 }; void init(void)

colormat. c GLfloat diffuse. Material[4] = { 0. 5, 1. 0 }; void init(void) { GLfloat mat_specular[] = { 1. 0, 1. 0 }; GLfloat light_position[] = { 1. 0, 0. 0 }; gl. Clear. Color (0. 0, 0. 0); gl. Shade. Model (GL_SMOOTH); gl. Enable(GL_DEPTH_TEST); gl. Materialfv(GL_FRONT, GL_DIFFUSE, diffuse. Material); gl. Materialfv(GL_FRONT, GL_SPECULAR, mat_specular); gl. Materialf(GL_FRONT, GL_SHININESS, 25. 0); gl. Lightfv(GL_LIGHT 0, GL_POSITION, light_position); gl. Enable(GL_LIGHTING); gl. Enable(GL_LIGHT 0); gl. Color. Material(GL_FRONT, GL_DIFFUSE); gl. Enable(GL_COLOR_MATERIAL); } void display(void){ gl. Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glut. Solid. Sphere(1. 0, 20, 16); gl. Flush (); }

void mouse(int button, int state, int x, int y) { switch (button) { case

void mouse(int button, int state, int x, int y) { switch (button) { case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { diffuse. Material[0] += 0. 1; if (diffuse. Material[0] > 1. 0) diffuse. Material[0] = 0. 0; gl. Color 4 fv(diffuse. Material); glut. Post. Redisplay(); } break;

movelight. c void display(void) { GLfloat position[ ] = { 0. 0, 1. 5,

movelight. c void display(void) { GLfloat position[ ] = { 0. 0, 1. 5, 1. 0 }; gl. Clear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); gl. Push. Matrix (); glu. Look. At (0. 0, 5. 0, 0. 0, 1. 0, 0. 0); gl. Push. Matrix (); gl. Rotated ((GLdouble) spin, 1. 0, 0. 0); gl. Lightfv (GL_LIGHT 0, GL_POSITION, position); gl. Translated (0. 0, 1. 5); gl. Disable (GL_LIGHTING); gl. Color 3 f (0. 0, 1. 0); glut. Wire. Cube (0. 1); gl. Enable (GL_LIGHTING); gl. Pop. Matrix (); glut. Solid. Torus (0. 275, 0. 85, 8, 15); gl. Pop. Matrix (); gl. Flush (); }

Lit. Jet. cpp (ch 5) void Setup. RC() { // Light values and coordinates

Lit. Jet. cpp (ch 5) void Setup. RC() { // Light values and coordinates GLfloat ambient. Light[] = { 0. 3 f, 1. 0 f }; GLfloat diffuse. Light[] = { 0. 7 f, 1. 0 f }; gl. Enable(GL_DEPTH_TEST); // Hidden surface removal gl. Front. Face(GL_CCW); // Counterclockwise polygons face out gl. Enable(GL_CULL_FACE); // Do not calculate inside of jet // Enable lighting gl. Enable(GL_LIGHTING); // Set up and enable light 0 gl. Lightfv(GL_LIGHT 0, GL_AMBIENT, ambient. Light); gl. Lightfv(GL_LIGHT 0, GL_DIFFUSE, diffuse. Light); gl. Enable(GL_LIGHT 0); // Enable color tracking gl. Enable(GL_COLOR_MATERIAL); // Set material properties to follow gl. Color values gl. Color. Material(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // Light blue background gl. Clear. Color(0. 0 f, 1. 0 f ); // Rescale normals to unit length gl. Enable(GL_NORMALIZE); }

void Render. Scene(void) { M 3 DVector 3 f v. Normal; // Storeage for

void Render. Scene(void) { M 3 DVector 3 f v. Normal; // Storeage for calculated surface normal { M 3 DVector 3 f v. Points[3] = {{ 15. 0 f, 0. 0 f, 30. 0 f}, { 0. 0 f, 15. 0 f, 30. 0 f}, { 0. 0 f, 60. 0 f}}; // Calculate the normal for the plane m 3 d. Find. Normal(v. Normal, v. Points[0], v. Points[1], v. Points[2]); gl. Normal 3 fv(v. Normal); gl. Vertex 3 fv(v. Points[0]); gl. Vertex 3 fv(v. Points[1]); gl. Vertex 3 fv(v. Points[2]); }

 • The most obvious way to improve the performance of this code is

• 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 Render. Scene 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.

Shiny. Jet. cpp (ch 5) Adding Specular Highlights

Shiny. Jet. cpp (ch 5) Adding Specular Highlights

 • • Specular lighting and material properties add needed gloss to the surface

• • 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 ambient. Light[] = { 0. 3 f, 1. 0 f }; GLfloat diffuse. Light[] = { 0. 7 f, 1. 0 f }; GLfloat specular[] = { 1. 0 f, 1. 0 f}; . . . // Enable lighting gl. Enable(GL_LIGHTING); // Set up and enable light 0 gl. Lightfv(GL_LIGHT 0, GL_AMBIENT, ambient. Light); gl. Lightfv(GL_LIGHT 0, GL_DIFFUSE, diffuse. Light); gl. Lightfv(GL_LIGHT 0, GL_SPECULAR, specular); gl. Enable(GL_LIGHT 0); • 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.

Adding specular reflectance to material properties // Light values and coordinates GLfloat specref[] =

Adding specular reflectance to material properties // Light values and coordinates GLfloat specref[] = { 1. 0 f, 1. 0 f }; . . . // Enable color tracking gl. Enable(GL_COLOR_MATERIAL); // Set material properties to follow gl. Color values gl. Color. Material(GL_FRONT, GL_AMBIENT_AND_DIFFUSE); // All materials hereafter have full specular reflectivity // with a high shine gl. Materialfv(GL_FRONT, GL_SPECULAR, specref); gl. Materiali(GL_FRONT, GL_SHININESS, 128); //The range of this parameter is 1– 128 for all conformant implementations of Open. GL.

Spot. cpp (ch 5) • This program places a blue sphere in the center

Spot. cpp (ch 5) • 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 downarrow 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 Open. GL!). – By lighting the vertices and then interpolating between them, we get a crude approximation of lighting.

GLfloat light. Pos[] = { 0. 0 f, 75. 0 f, 1. 0 f

GLfloat light. Pos[] = { 0. 0 f, 75. 0 f, 1. 0 f }; GLfloat specular[] = { 1. 0 f, 1. 0 f}; GLfloat specref[] = { 1. 0 f, 1. 0 f }; GLfloat ambient. Light[] = { 0. 5 f, 1. 0 f}; GLfloat spot. Dir[] = { 0. 0 f, -1. 0 f }; void Setup. RC() { gl. Enable(GL_DEPTH_TEST); // Hidden surface removal gl. Front. Face(GL_CCW); // Counterclockwise polygons face out gl. Enable(GL_CULL_FACE); // Do not try to display the back sides // Enable lighting gl. Enable(GL_LIGHTING); // Set up and enable light 0 // Supply a slight ambient light so the objects can be seen gl. Light. Modelfv(GL_LIGHT_MODEL_AMBIENT, ambient. Light); // The light is composed of just diffuse and specular components gl. Lightfv(GL_LIGHT 0, GL_DIFFUSE, ambient. Light); gl. Lightfv(GL_LIGHT 0, GL_SPECULAR, specular); gl. Lightfv(GL_LIGHT 0, GL_POSITION, light. Pos); // Specific spot effects. This line what makes a positional light source into a spotlight: gl. Lightf(GL_LIGHT 0, GL_SPOT_CUTOFF, 60. 0 f); // Enable this light in particular gl. Enable(GL_LIGHT 0);

CAN YOU SEE THE LIGHT? • No. • Lights in Open. GL cannot be

CAN YOU SEE THE LIGHT? • No. • Lights in Open. GL 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 Open. GL, 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.

void Render. Scene(void) { if(i. Shade == MODE_FLAT) gl. Shade. Model(GL_FLAT); else // i.

void Render. Scene(void) { if(i. Shade == MODE_FLAT) gl. Shade. Model(GL_FLAT); else // i. Shade = MODE_SMOOTH; gl. Shade. Model(GL_SMOOTH); // Clear the window with current clearing color gl. Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // First place the light // Save the coordinate transformation gl. Push. Matrix(); // Rotate coordinate system gl. Rotatef(y. Rot, 0. 0 f, 1. 0 f, 0. 0 f); gl. Rotatef(x. Rot, 1. 0 f, 0. 0 f); // Specify new position and direction in rotated coords gl. Lightfv(GL_LIGHT 0, GL_POSITION, light. Pos); gl. Lightfv(GL_LIGHT 0, GL_SPOT_DIRECTION, spot. Dir);

// Draw a red cone to enclose the light source gl. Color 3 ub(255,

// Draw a red cone to enclose the light source gl. Color 3 ub(255, 0, 0); // Translate origin to move the cone out to where the light // is positioned. gl. Translatef(light. Pos[0], light. Pos[1], light. Pos[2]); glut. Solid. Cone(4. 0 f, 6. 0 f, 15); // Draw a smaller displaced sphere to denote the light bulb // Save the lighting state variables gl. Push. Attrib(GL_LIGHTING_BIT); // Turn off lighting and specify a bright yellow sphere gl. Disable(GL_LIGHTING); gl. Color 3 ub(255, 0); glut. Solid. Sphere(3. 0 f, 15); // Restore lighting state variables gl. Pop. Attrib(); // Restore coordinate transformations gl. Pop. Matrix();

// Set material color and draw a sphere in the middle gl. Color 3

// Set material color and draw a sphere in the middle gl. Color 3 ub(0, 0, 255); if(i. Tess == MODE_VERYLOW) glut. Solid. Sphere(30. 0 f, 7, 7); else if(i. Tess == MODE_MEDIUM) glut. Solid. Sphere(30. 0 f, 15); else // i. Tess = MODE_MEDIUM; glut. Solid. Sphere(30. 0 f, 50); // Display the results glut. Swap. Buffers(); }

Shadows

Shadows

Squish Code • We need to flatten the modelview matrix so that any and

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 m 3 d. Make. Planar. Shadow. Matrix from the math 3 d 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 m 3 d. Get. Plane. Equation 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.

Shadow. cpp (ch 5) GLfloat light. Pos[] = { -75. 0 f, 150. 0

Shadow. cpp (ch 5) GLfloat light. Pos[] = { -75. 0 f, 150. 0 f, -50. 0 f, 0. 0 f }; . . . // Transformation matrix to project shadow M 3 DMatrix 44 f shadow. Mat; . . . void Setup. RC() { // Any three points on the ground (counterclockwise order) M 3 DVector 3 f points[3] = {{ -30. 0 f, -149. 0 f, -20. 0 f }, { -30. 0 f, -149. 0 f, 20. 0 f }, { 40. 0 f, -149. 0 f, 20. 0 f }}; gl. Enable(GL_DEPTH_TEST); // Hidden surface removal gl. Front. Face(GL_CCW); // Counterclockwise polygons face out gl. Enable(GL_CULL_FACE); // Do not calculate inside of jet gl. Enable(GL_LIGHTING); ……. // Get the plane equation from three points on the ground M 3 DVector 4 f v. Plane. Equation; m 3 d. Get. Plane. Equation(v. Plane. Equation, points[0], points[1], points[2]); // Calculate projection matrix to draw shadow on the ground m 3 d. Make. Planar. Shadow. Matrix(shadow. Mat, v. Plane. Equation, light. Pos); . . . }

void Render. Scene(void) { // Clear the window with current clearing color gl. Clear(GL_COLOR_BUFFER_BIT

void Render. Scene(void) { // Clear the window with current clearing color gl. Clear(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 gl. Begin(GL_QUADS); gl. Color 3 ub(0, 32, 0); gl. Vertex 3 f(400. 0 f, -150. 0 f, -200. 0 f); gl. Vertex 3 f(-400. 0 f, -150. 0 f, -200. 0 f); gl. Color 3 ub(0, 255, 0); gl. Vertex 3 f(-400. 0 f, -150. 0 f, 200. 0 f); gl. Vertex 3 f(400. 0 f, -150. 0 f, 200. 0 f); gl. End(); // Save the matrix state and do the rotations gl. Push. Matrix(); // Draw jet at new orientation; put light in correct position // before rotating the jet gl. Enable(GL_LIGHTING); gl. Lightfv(GL_LIGHT 0, GL_POSITION, light. Pos); gl. Rotatef(x. Rot, 1. 0 f, 0. 0 f); gl. Rotatef(y. Rot, 0. 0 f, 1. 0 f, 0. 0 f);

Draw. Jet(FALSE); // Restore original matrix state gl. Pop. Matrix(); // Get ready to

Draw. Jet(FALSE); // Restore original matrix state gl. Pop. Matrix(); // Get ready to draw the shadow and the ground // First disable lighting and save the projection state gl. Disable(GL_DEPTH_TEST); gl. Disable(GL_LIGHTING); gl. Push. Matrix(); // Multiply by shadow projection matrix gl. Mult. Matrixf((GLfloat *)shadow. Mat); // Now rotate the jet around in the new flattened space gl. Rotatef(x. Rot, 1. 0 f, 0. 0 f); gl. Rotatef(y. Rot, 0. 0 f, 1. 0 f, 0. 0 f); // Pass true to indicate drawing shadow Draw. Jet(TRUE); // Restore the projection to normal gl. Pop. Matrix();

// Draw the light source gl. Push. Matrix(); gl. Translatef(light. Pos[0], light. Pos[1], light.

// Draw the light source gl. Push. Matrix(); gl. Translatef(light. Pos[0], light. Pos[1], light. Pos[2]); gl. Color 3 ub(255, 0); glut. Solid. Sphere(5. 0 f, 10); gl. Pop. Matrix(); // Restore lighting state variables gl. Enable(GL_DEPTH_TEST); // Display the results glut. Swap. Buffers(); }

Sphere. World. cpp (ch 5)

Sphere. World. cpp (ch 5)