15-462 Computer Graphics I Lecture 8
Shading in OpenGL
Shading in OpenGL
Polygonal Shading
Polygonal Shading
Light Source in OpenGL
Light Source in OpenGL
Material Properties in OpenGL
Material Properties in OpenGL
Normal Vectors in OpenGL
Normal Vectors in OpenGL
Approximating a Sphere
Approximating a Sphere
[Angel 6.5-6.9]
[Angel 6.5-6.9]
February 6, 2003
Frank Pfenning
Carnegie Mellon University
http://www.cs.cmu.edu/~fp/courses/graphics/
Polygonal Shading
Polygonal Shading
• Curved surfaces are approximated by polygons
• How do we shade? – Flat shading
– Interpolative shading – Gouraud shading
– Phong shading (different from Phong illumination)
• Two questions:
– How do we determine normals at vertices?
– How do we calculate shading at interior points?
02/06/2003 15-462 Graphics I 2
Flat Shading
Flat Shading
• Normal: given explicitly before vertex
glNormal3f(nx, ny, nz); glVertex3f(x, y, z);
• Shading constant across polygon
• Single polygon: first vertex
• Triangle strip:Vertex n+2 for triangle n
02/06/2003 15-462 Graphics I 3
Flat Shading Assessment
Flat Shading Assessment
• Inexpensivetocompute
• Appropriateforobjectswithflatfaces • Lesspleasantforsmoothsurfaces
02/06/2003 15-462 Graphics I 4
Interpolative Shading
Interpolative Shading
• Enable with glShadeModel(GL_SMOOTH);
• Calculatecolorateachvertex
• Interpolatecolorininterior
• Compute during scan conversion (rasterization) • Much better image (see Assignment 1)
• Moreexpensivetocalculate
02/06/2003 15-462 Graphics I 5
Gouraud Shading
Gouraud Shading
• Specialcaseofinterpolativeshading
• How do we calculate vertex normals?
• Gouraud:averagealladjacentfacenormals
• Requires knowledge about which faces share a vertex
02/06/2003 15-462 Graphics I 6
Data Structures for Gouraud Shading
Data Structures for Gouraud Shading
• Sometimesvertexnormalscanbecomputed directly (e.g. height field with uniform mesh)
• More generally, need data structure for mesh • Key: which polygons meet at each vertex
02/06/2003 15-462 Graphics I 7
Phong Shading
Phong Shading
• Interpolatenormalsratherthancolors
• Significantly more expensive
• Mostlydoneoff-line(notsupportedinOpenGL)
02/06/2003 15-462 Graphics I 8
Phong Shading Results
Phong Shading Results
Michael Gold, Nvidia
Single pass Phong Lighting Gouraud Shading
02/06/2003
Two pass Phong Lighting, Gouraud Shading
15-462 Graphics I
Two pass Phong Lighting, Phong Shading
9
Polygonal Shading Summary
Polygonal Shading Summary
• Gouraud shading – Set vertex normals
– Calculate colors at vertices
– Interpolate colors across polygon
• Must calculate vertex normals!
• Must normalize vertex normals to unit length!
02/06/2003 15-462 Graphics I 10
Outline
Outline
• Polygonal Shading
• Light Sources in OpenGL
• MaterialPropertiesinOpenGL
• NormalVectorsinOpenGL
• Example: Approximating a Sphere
02/06/2003 15-462 Graphics I 11
Enabling Lighting and Lights
Enabling Lighting and Lights
• Lighting in general must be enabled
glEnable(GL_LIGHTING);
• Each individual light must be enabled
glEnable(GL_LIGHT0);
• OpenGLsupportsatleast8lightsources
02/06/2003 15-462 Graphics I 12
Global Ambient Light
Global Ambient Light
• Setambientintensityforentirescene
GLfloat al[] = {0.2, 0.2, 0.2, 1.0}; glLightModelfv(GL_LIGHT_MODEL_AMBIENT, al);
• The above is default
• Also: local vs infinite viewer
glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
• Moreexpensive,butsometimesmoreaccurate 02/06/2003 15-462 Graphics I 13
Defining a Light Source
Defining a Light Source
• Usevectors{r,g,b,a}forlightproperties • Beware: light source will be transformed!
GLfloat light_ambient[] = {0.2, 0.2, 0.2, 1.0};
GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat light_specular[] = {1.0, 1.0, 1.0, 1.0};
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);
02/06/2003 15-462 Graphics I 14
Point Source vs Directional Source
Point Source vs Directional Source
• Directional light given by “position” vector GLfloat light_position[] = {-1.0, 1.0, -1.0, 0.0};
glLightfv(GL_LIGHT0, GL_POSITION, light_position); • Point source given by “position” point
GLfloat light_position[] = {-1.0, 1.0, -1.0, 1.0}; glLightfv(GL_LIGHT0, GL_POSITION, light_position);
02/06/2003 15-462 Graphics I 15
Spotlights
Spotlights
• Create point source as before
• Specifyadditionalpropertiestocreatespotlight
GLfloat sd[] = {-1.0, -1.0, 0.0}; glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, sd); glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0); glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);
[Demo: Lighting Position Tutor]
02/06/2003 15-462 Graphics I 16
Outline
Outline
• Polygonal Shading
• Light Sources in OpenGL
• MaterialPropertiesinOpenGL
• NormalVectorsinOpenGL
• Example: Approximating a Sphere
02/06/2003 15-462 Graphics I 17
Defining Material Properties
Defining Material Properties
• Materialpropertiesstayineffect
• Setbothspecularcoefficientsandshininess
GLfloat mat_d[] = {0.1, 0.5, 0.8, 1.0};
GLfloat mat_s[] = {1.0, 1.0, 1.0, 1.0};
GLfloat low_sh[] = {5.0};
glMaterialfv(GL_FRONT, GL_AMBIENT, mat_d); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_s); glMaterialfv(GL_FRONT, GL_SHININESS, low_sh);
• Diffusecomponentisanalogous
[Demo: Light material Tutor]
02/06/2003 15-462 Graphics I 18
Color Material Mode (Answer)
Color Material Mode (Answer)
• CanshortcutmaterialpropertiesusingglColor • Must be explicitly enabled and disabled
glEnable(GL_COLOR_MATERIAL);
/* affect front face, diffuse reflection properties */ glColorMaterial(GL_FRONT, GL_DIFFUSE); glColor3f(0.0, 0.0, 0.8);
/* draw some objects here in blue */ glColor3f(1.0, 0.0, 0.0);
/* draw some objects here in red */ glDisable(GL_COLOR_MATERIAL);
02/06/2003 15-462 Graphics I 19
Outline
Outline
• Polygonal Shading
• Light Sources in OpenGL
• MaterialPropertiesinOpenGL
• NormalVectorsinOpenGL
• Example: Approximating a Sphere
02/06/2003 15-462 Graphics I 20
Defining and Maintaining Normals
Defining and Maintaining Normals
• Defineunitnormalbeforeeachvertex glNormal3f(nx, ny, nz);
glVertex3f(x, y, z);
• Lengthchangesundersometransformations
• Ask OpenGL to re-normalize (all tfms)
glEnable(GL_NORMALIZE);
• AskOpenGLtore-scalenormal glEnable(GL_RESCALE_NORMAL);
• Works for uniform scaling (and rotate, translate) 02/06/2003 15-462 Graphics I 21
Example: Icosahedron
Example: Icosahedron
• Define the vertices
#define X .525731112119133606 #define Z .850650808352039932
static GLfloat vdata[12][3] = {
{-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z}, {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X}, {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};
• For simplicity, avoid the use of vertex arrays
02/06/2003 15-462 Graphics I 22
Defining the Faces
Defining the Faces
• Index into vertex data array
static GLuint tindices[20][3] = {
{1,4,0}, {4,9,0}, {4,9,5}, {8,5,4}, {1,8,4}, {1,10,8}, {10,3,8}, {8,3,5}, {3,2,5}, {3,7,2}, {3,10,7}, {10,6,7}, {6,11,7}, {6,0,11}, {6,1,0}, {10,1,6}, {11,0,9}, {2,11,9}, {5,2,9}, {11,2,7}
};
• Becarefulaboutorientation!
02/06/2003 15-462 Graphics I 23
Drawing the Icosahedron
Drawing the Icosahedron
• Normal vector calculation next
glBegin(GL_TRIANGLES); for (i = 0; i < 20; i++) {
icoNormVec(i); glVertex3fv(&vdata[tindices[i][0]] [0]); glVertex3fv(&vdata[tindices[i][1]] [0]); glVertex3fv(&vdata[tindices[i][2]] [0]);
} glEnd();
• Should be encapsulated in display list
02/06/2003 15-462 Graphics I 24
Calculating the Normal Vectors
Calculating the Normal Vectors
• Normalized cross product of any two sides GLfloat d1[3], d2[3], n[3];
void icoNormVec (int i) { for (k = 0; k < 3; k++) {
d1[k] = vdata[tindices[i][0]] [k] – vdata[tindices[i][1]] [k];
d2[k] = vdata[tindices[i][1]] [k] – vdata[tindices[i][2]] [k]; }
normCrossProd(d1, d2, n); glNormal3fv(n);
}
02/06/2003 15-462 Graphics I 25
The Normalized Cross Product
The Normalized Cross Product
• Omitzero-checkforbrevity
void normalize(float v[3]) {
GLfloat d = sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); v[0] /= d; v[1] /= d; v[2] /= d;
}
void normCrossProd(float u[3], float v[3], float out[3]) { out[0] = u[1]*v[2] – u[2]*v[1];
out[1] = u[2]*v[0] – u[0]*v[2];
out[2] = u[0]*v[1] – u[1]*v[0];
normalize(out); }
02/06/2003 15-462 Graphics I 26
The Icosahedron
The Icosahedron
• Using simple lighting setup
02/06/2003 15-462 Graphics I 27
Sphere Normals
Sphere Normals
• Setupinsteadtousenormalsofsphere
• Unitspherenormalisexactlyspherepoint
glBegin(GL_TRIANGLES); for (i = 0; i < 20; i++) {
glNormal3fv(&vdata[tindices[i][0]][0]); glVertex3fv(&vdata[tindices[i][0]][0]); glNormal3fv(&vdata[tindices[i][1]][0]); glVertex3fv(&vdata[tindices[i][1]][0]); glNormal3fv(&vdata[tindices[i][2]][0]); glVertex3fv(&vdata[tindices[i][2]][0]);
} glEnd();
02/06/2003 15-462 Graphics I 28
Icosahedron with Sphere Normals
Icosahedron with Sphere Normals
• Interpolationvsflatshadingeffect
02/06/2003 15-462 Graphics I 29
Recursive Subdivision
Recursive Subdivision
• Generalmethodforbuildingapproximations
• Researchtopic:constructagoodmesh – Low curvature, fewer mesh points
– High curvature, more mesh points
– Stop subdivision based on resolution
– Some advanced data structures for animation – Interaction with textures
• Here: simplest case
• Approximatespherebysubdividing icosahedron
02/06/2003 15-462 Graphics I 30
Methods of Subdivision
Methods of Subdivision
• Bisecting angles • Computing center • Bisecting sides
• Here:bisectsidestoretainregularity
02/06/2003 15-462 Graphics I 31
Bisection of Sides
Bisection of Sides
• Drawifnofurthersubdivisionrequested
void subdivide(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], int depth)
{ GLfloat v12[3], v23[3], v31[3]; int i;
if (depth == 0) { drawTriangle(v1, v2, v3); } for (i = 0; i < 3; i++) {
v12[i] = (v1[i]+v2[i])/2.0; v23[i] = (v2[i]+v3[i])/2.0; v31[i] = (v3[i]+v1[i])/2.0;
} ...
02/06/2003 15-462 Graphics I 32
Extrusion of Midpoints
Extrusion of Midpoints
• Re-normalizemidpointstolieonunitsphere
void subdivide(GLfloat v1[3], GLfloat v2[3], GLfloat v3[3], int depth)
{ ...
normalize(v12);
normalize(v23);
normalize(v31);
subdivide(v1, v12, v31, depth-1); subdivide(v2, v23, v12, depth-1); subdivide(v3, v31, v23, depth-1); subdivide(v12, v23, v31, depth-1);
}
02/06/2003 15-462 Graphics I 33
Start with Icosahedron
Start with Icosahedron
• Insamplecode:controldepthwith‘+’and‘-’
void display(void) { ...
for (i = 0; i < 20; i++) { subdivide(&vdata[tindices[i][0]][0],
&vdata[tindices[i][1]][0], &vdata[tindices[i][2]][0], depth);
}
glFlush(); }
02/06/2003
15-462 Graphics I 34
One Subdivision
One Subdivision
02/06/2003 15-462 Graphics I 35
Two Subdivisions
Two Subdivisions
• Each time, multiply number of faces by 4
02/06/2003 15-462 Graphics I 36
Three Subdivisions
Three Subdivisions
• Reasonableapproximationtosphere
02/06/2003 15-462 Graphics I 37
Example Lighting Properties
Example Lighting Properties
GLfloat light_ambient[]={0.2, 0.2, 0.2, 1.0}; GLfloat light_diffuse[]={1.0, 1.0, 1.0, 1.0}; GLfloat light_specular[]={0.0, 0.0, 0.0, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
02/06/2003 15-462 Graphics I 38
Example Material Properties
Example Material Properties
GLfloat mat_specular[]={0.0, 0.0, 0.0, 1.0};
GLfloat mat_diffuse[]={0.8, 0.6, 0.4, 1.0};
GLfloat mat_ambient[]={0.8, 0.6, 0.4, 1.0};
GLfloat mat_shininess={20.0};
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialf(GL_FRONT, GL_SHININESS, mat_shininess);
glShadeModel(GL_SMOOTH); /*enable smooth shading */ glEnable(GL_LIGHTING); /* enable lighting */ glEnable(GL_LIGHT0); /* enable light 0 */
02/06/2003 15-462 Graphics I 39
Summary
Summary
• Polygonal Shading
• Light Sources in OpenGL
• MaterialPropertiesinOpenGL
• NormalVectorsinOpenGL
• Example: Approximating a Sphere
02/06/2003 15-462 Graphics I 40
Preview
Preview
• Either
– Basic texture mapping – Curves and surfaces
02/06/2003 15-462 Graphics I 41