190 likes | 1.01k Views
Specular Reflection and OpenGL Lighting. Soon Tee Teoh CS 116A. Specular Reflection. Specular reflection is for shiny objects In contrast to diffuse reflection, specular reflection is not constant at all angles from the surface.
E N D
Specular Reflection and OpenGL Lighting Soon Tee Teoh CS 116A
Specular Reflection • Specular reflection is for shiny objects • In contrast to diffuse reflection, specular reflection is not constant at all angles from the surface. • Specular reflection is the strongest at the specular reflection direction R. N R L q q Vector L is the direction to the light source. Vector N is the normal vector of the surface.
Specular Reflection Model • The Phong Specular Reflection Model • How much specular reflection is emitted at an arbitrary direction V? • This depends on the angle f between V and R. • The larger the angle f, the less is the reflection. N R L V q q f Vector L is the direction to the light source. Vector N is the normal vector of the surface. Vector R is the specular reflection direction.
Phong Specular Model • We use a shininess factor n. Bigger value of n indicates that the surface is more shiny. • Then, the light reflected in the direction of V will be proportional to cosn f. • When n increases, cosnf decays more quickly to zero as f increases.
Fresnel’s Laws of Reflection • The amount of light reflected also depends on the angle at which the incident light L strikes the surface. • Some materials (such as water surface) obey Fresnel’s Law. According to this model, when q is 0o, that is, when light hits the surface straight on, a lot of light goes through the object. When light hits the surface at a glancing angle, that is when q is almost 90o, most of the light is reflected. • Therefore, Ispecular = W(q)Ilightcosnf W(q) describes how the angle at which the light hits the surface affects the amount of reflection.
Simplified Specular Model • We can simply consider W(q) to be constant. • Therefore, Ispec = kIlightcosnf. • But what is cos f? cos f = V.R • V is given (the viewing direction). But what is R? The projection of L onto N is N.L. Then, according to the diagram below, R + L = (2N.L)N Rearranging, R = (2N.L)N - L L N L N.L R
Further Simplified Specular Model • Instead of using V.R (for cos f), we use N.H (for cos a), where N is the normal of the surface, and H is the halfway vector between L and V. • When L, N and V are co-planar, a = f/2. • We use N.H instead of V.R because N.H requires less calculations. L + V H = | L + V | light source center of reflection N H a R L eye f V
Combined Lighting Model The illumination due to diffuse reflection of incident light The illumination due to ambient light The illumination due to specular reflection of incident light The illumination of the surface I = Iambient + Idiffuse + Ispecular = kaIa + kdIlight(N.L) + ksIlight(N.H)n The intensity of the ambient light The intensity of the incident light
Illumination in OpenGL • How an object is illuminated depends on • (1) its material, and • (2) the properties of the light source.
OpenGL Lighting • First, enable lighting with • Then, you can set up a global ambient light with • Then you can create other light sources glEnable(GL_LIGHTING); GLfloat f_array[] = { 0.2, 0.2, 0.2, 1.0); // color in RGBA mode, just set a to 1 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, f_array);
Setting up a light source • At least 8 light sources are supported. They are named GL_LIGHT0, GL_LIGHT1, GL_LIGHT2 etc. • Set the position and color of a light source. • For each light source, we can set a different ambient, diffuse and specular component to the light source. • The position is set with a 4-element array, treated as (x,y,z,w). When w is 0, the light source is treated as a directional light infinitely far away in the direction of (x,y,z). When w is not 0, then the light source is treated as a point light source situated at (x,y,z). • Finally, enable that light source. GLfloat amb_color[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat diff_color[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat spec_color[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat pos[] = { 0.0, 1.0, 0.0, 1.0 }; // point light source at (0,1,0) glLightfv(GL_LIGHT1, GL_AMBIENT, amb_color); glLightfv(GL_LIGHT1, GL_DIFFUSE, diff_color); glLightfv(GL_LIGHT1, GL_SPECULAR, spec_color); glLightfv(GL_LIGHT1, GL_POSITION, pos); glEnable(GL_LIGHT1);
Optional Attenuation • You can optionally add an attenuation factor to a positional light source. • The attenuation factor is 1/(k0 + k1d + k2d2) where k0, k1 and k2 can be set, and d is the distance from the light source. • Set attenuation for a light source like this: glLightf( GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0); // sets k0 glLightf( GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0); // sets k1 glLightf( GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5); // sets k2
Making a Spotlight • You can turn a point light source into a spotlight by setting some parameters: (1) the spotlight direction v, (2) the spotlight cutoff a, and (3) the spotlight exponent n • The light will only be shone in the direction specified, with no light in the direction beyond the cutoff angle. • Within the cutoff, the light intensity decays by a factor of cosnq, where q is the angle from the direction. direction Light source cutoff GLfloat dir[] { -1.0, -1.0, 0.0 }; glLightf( GL_LIGHT5, GL_SPOT_CUTOFF, 30.0); glLightfv( GL_LIGHT5, GL_SPOT_DIRECTION, dir); glLightf( GL_LIGHT5, GL_SPOT_EXPONENT, 2.0);
Example: Making a Spotlight with Attenuation GLfloat amb_color[] = { 0.2, 0.2, 0.2, 1.0 }; GLfloat diff_color[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat spec_color[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat pos[] = { 0.0, 1.0, 0.0, 1.0 }; // point light source at (0,1,0) GLfloat dir[] { -1.0, -1.0, 0.0 }; glLightfv(GL_LIGHT1, GL_AMBIENT, amb_color); glLightfv(GL_LIGHT1, GL_DIFFUSE, diff_color); glLightfv(GL_LIGHT1, GL_SPECULAR, spec_color); glLightfv(GL_LIGHT1, GL_POSITION, pos); glLightf( GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0); // sets k0 glLightf( GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0); // sets k1 glLightf( GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.5); // sets k2 glLightf( GL_LIGHT1, GL_SPOT_CUTOFF, 30.0); glLightfv( GL_LIGHT1, GL_SPOT_DIRECTION, dir); glLightf( GL_LIGHT1, GL_SPOT_EXPONENT, 2.0); glEnable(GL_LIGHT1);
OpenGL Materials • You are able to set the ambient color, diffuse color, specular color and emissive color of a material. • You can set the front face, back face or both faces. • By default, the face with counter-clockwise vertices is considered to be the front face. (You can change this with glFrontFace(GL_CW).) GLfloat col0[] = { 1.0, 0.5, 0.2, 1.0 }; // RGBA GLfloat col1[] = { 1.0, 1.0, 0.2, 1.0 }; // RGBA GLfloat col2[] = { 0.0, 0.1, 0.1, 1.0 }; // RGBA GLfloat col3[] = { 0.2, 0.1, 0.9, 1.0 }; // RGBA glMaterialfv(GL_FRONT, GL_AMBIENT, col0); glMaterialfv(GL_FRONT, GL_SPECULAR, col1); glMaterialfv(GL_FRONT, GL_EMISSION, col2); glMaterialfv(GL_FRONT, GL_DIFFUSE, col3); For convenience, can set ambient and diffuse color together with the same color by passing the argument GL_AMBIENT_AND_DIFFUSE Can also be GL_BACK or GL_FRONT_AND_BACK
Shininess for Specular Reflection • You can also set the shininess for specular reflection with: glMaterialf(GL_FRONT, GL_SHININESS, 2.0); Provide a shininess value here. The larger the value, the more shiny.
Need to provide normal for each polygon • In order for OpenGL to perform lighting calculations, you need to supply the normal vectors. • Do that using cross product (of edges listed in counter-clockwise order) as covered in previous lectures. • Then, you need to normalize the normals, that is, to make sure that they are unit length. You can do this with your own code, or you can call glEnable(GL_NORMALIZE). • For the GLUT and GLU objects (e.g. glutSolidSphere), the normals are already provided by the GLUT and GLU calls, but for objects you create with GL_TRIANGLES, GL_QUADS and GL_POLYGON, you need to specify the normals. glBegin(GL_QUADS); glNormal3f(0,0,1); glVertex3f(0,0,1); glVertex3f(1,0,1); glVertex3f(1,1,1); glVertex3f(0,1,1); glEnd();
Effect of Material and Lighting in OpenGL Vertex color = Coloremission,material + Colorglobal_ambient_light x Colorambient,material + S[(1/(k0+k1d+k2d2))i x (v.d)ni x (Coloramb,reflection + Colordiff,reflection + Colorspec,reflection)i] Direction from light to vertex Angular attenuation factor Spotlight direction n i = 0 Attenuation Spotlight effect Sum for each light source where k0, k1, k2, d, and n are set by the user. Colorambient,reflection, Colordiffuse,reflection and Colorspecular,reflection are given next page.
Ambient, Diffuse and Specular Reflection for each light source Colorambient,reflection = Colorambient,light x Colorambient,material Colordiffuse,reflection = L.N x Colordiffuse,light x Colordiffuse,material Colorspecular,reflection = N.Hshininess x Colorspecular,light x Colorspecular,material