project 5 lamp shader fri, nov 7, 2003 due mon, nov 17, 2003

Post on 14-Jan-2016

224 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Project 5

Lamp ShaderFri, Nov 7, 2003Due Mon, Nov 17, 2003

Lamp Shader

Read the handout.Download the files.

LampShader.cpp. mesh.h. mesh.cpp. point3.h. point3.cpp. vector3.h. vector3.cpp. face.h. vertexid.h.

Run LampShader.exe.

Lamp Shader

The primary purpose of this project is to compute the lighting of a vertex, and therefore of a mesh, in a way that exactly matches the lighting calculated by the graphics pipeline.

The Scene

The scene consists of a lamp with a lampshade.Each object is represented as a mesh.The basic shapes are spheres, cylinders, cones, and toruses.

The Basic Meshes

sphere “cylinder” cone torus

The Basic Meshes

These correspond to meshes that are available from the glu and glut libraries. gluSphere(obj, radius, slices, stacks). gluCylinder(obj, baseRad, topRad, height,

slices, stacks). glutSolidCone(radius, height, slices, stacks). glutSolidTorus(innerRad, outerRad, nsides,

rings).

The Basic Meshes

If we used the library functions, that would present two problems in trying to compute the lighting at a vertex. How would we obtain access to the

coordinates and normal at a vertex? Even if we did have that access, how

would we know the transformed coordinates and normals at a vertex?

The Basic Meshes

To avoid both of these problems, we will use our own meshes.The program LampShader.cpp uses the Mesh-class function create() to create a mesh.Among the parameters are functions to compute the vertices and normals in terms of parameters u and v.

The Basic Meshes

This solves the problem of access to the coordinates and normals of the meshes.They are stored in the data members of the Mesh object. Point3* pt; Vector3* norm;

Transforming the Meshes

OpenGL has functions glTranslate(), glRotate(), and glScale() that will transform the meshes.However, we should not use them.Why not?Instead, the Mesh class has member functions that will translate, rotate, and scale the mesh.

Transforming the Meshes

Their prototypes are similar to the OpenGL functions. void translate(dx, dy, dz); void rotate(angle, ux, uy, uz); void scale(sx, sy, sz);

This solves the problem of access to the transformed coordinates and normals.

Transforming the Meshes

There is a consequence to transforming the points in the mesh object rather than leaving them alone and modifying the ModelView matrix.The transformations must appear in the order in which they are applied, not in reverse order.

Example

Mesh.create(…);Mesh.scale(1, 1, 2);Mesh.rotate(90, 0, 1, 0);Mesh.translate(2, 0, 0);Mesh.draw();

glMatrixMode(…);glLoadIdentity();glTranslatef(2, 0, 0);glRotatef(90, 0, 1, 0);glScalef(1, 1, 2);drawObject();

Compare

Accessing State Variables

The draw() function needs to know the values of various state variables concerning light and material properties. Light position. Light color for ambient, diffuse, and specular

light. The scene ambient light. Material reflection of ambient, diffuse, and

specular light. Material shininess.

Obtaining Light Properties

float lightAmbient[4];float lightDiffuse[4];float lightSpecular[4];glGetLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);glGetLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);glGetLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);float sceneAmbient[4];glGetFloatv(GL_LIGHT_MODEL_AMBIENT, sceneAmbient);

Obtaining Material Properties

float matAmbient[4];float matDiffuse[4];float matSpecular[4];float matShininess[1];glGetMaterialfv(GL_FRONT, GL_AMBIENT, matAmbient);glGetMaterialfv(GL_FRONT, GL_DIFFUSE, matDiffuse);glGetMaterialfv(GL_FRONT, GL_SPECULAR, matSpecular);glGetMaterialfv(GL_FRONT, GL_SHININESS, matShininess);

Computing Lighting

You should implement the formulas ra = sama + Lama.

rd = Ldmd(s n).

rs = Lsms(h n)shiny.

where sa = sceneAmbient. La = lightAmbient. Ld = lightDiffuse. Ls = lightSpecular.

Computing Lighting

and ma = matAmbient. md = matDiffuse. ms = matSpecular. shiny = matShininess.

Computing Lighting

The vectors needed are n = the surface normal. s = the vector to the light source. v = the vector to the viewer.

Each of these should be a unit vector.

Computing Lighting

n is contained in the Mesh object.s is computed from the point on the surface (pt) and the light position (lightPos).v is computed from the point on the surface (pt) and the location of the viewer (eye).lightPos, eye, and look are global external variables.

Drawing the Vertex

Once you have computed the color, you should set it, using glColor().Then draw the vertex in the usual way, using glVertex().Since OpenGL lighting is turned off (under software lighting), there will be no lighting effects added to the color that you set. (“What you set is what you get.”)

The Light Position

It is possible to obtain the position of the light source from a state variable. glGetLightfv(GL_LIGHT0, GL_POSITION, lightPos);

However, this gives its position after the view matrix has been applied!Thus, its coordinates are not in the same system as the point on the surface or the position of the viewer.

Infinite vs. Local Viewer

OpenGL treats the viewer as located “at infinity” only for the purpose of calculating specular lighting.The advantage is that the viewer vector v does not change from one point to another on the surface.

Infinite Viewer

The viewer is not truly at infinity.The vector v is the vector from the look point to the eye point.That single value of v is used for every point on the surface (as though the viewer were infinitely far away).

Local Viewer

If the viewer is “local,” then the viewer vector v is defined to be the vector from the point on the surface to the eye point, normalized.Thus, it must be recomputed for every point on the surface.

Positional vs. Directional Light

If the light is positional, then the light vector s goes from the point on the surface (pt) to the light source (lightPos) and must be recomputed for each point.If the light is directional, then it goes from the origin to the light source and need be computed only once.

Suggestions

Try implementing ambient light first, then diffuse light, then specular light.While debugging ambient light, turn off diffuse and specular light.While debugging diffuse light, turn off specular light.

Further Purposes of this Project

What is the value in doing the lighting calculations that OpenGL already does? Further awareness of how OpenGL works. Ability to modify the lighting model to

suit yourself, e.g., Phong vs. Blinn. For example, you might want to create a

“bike reflector” that reflects light back towards the light source.

Further Purposes of this Project

The latest graphics cards are programmable (in Cg): the programmer may program the lighting of each vertex or each pixel! A vertex program will color each vertex.

OpenGL will interpolate over the polygon. A fragment program will color each pixel.

top related