This page was last updated: January 16, 2025
| Parameter | What It Does | Does it have to be varied? |
|---|---|---|
| uKa | Ambient coefficient | No |
| uKd | Diffuse coefficient | No |
| uKs | Specular coefficient | No |
| uShininess | Specular exponent | No |
| uAd | Ellipse diameter in s | Yes |
| uBd | Ellipse diameter in t | Yes |
| uTol | Width of the blend between ellipse and non-ellipse areas | Yes |
A glman .glib file might look like this:
##OpenGL GLIB
Perspective 90
LookAt 0 0 2 0 0 0 0 1 0
Vertex oval.vert
Fragment oval.frag
Program Oval \
uKa <0.1 0.1 0.5> \
uKd <0.1 0.6 1.> \
uKs <0.1 0.3 1.> \
uShininess <1. 10. 25.> \
uAd <.001 .1 .5> \
uBd <.001 .1 .5> \
uTol <0. 0. 1.>
Sphere 1 50 50
// a defined value:
const int MSEC = 10000; // 10000 milliseconds = 10 seconds
// a global:
Keytimes Ad;
// in InitGraphics( ):
Ad.Init( );
Ad.AddTimeValue( 0.0, ????? );
Ad.AddTimeValue( 2.0, ????? );
Ad.AddTimeValue( 5.0, ????? );
Ad.AddTimeValue( 8.0, ????? );
Ad.AddTimeValue( 10.0, ????? );
// in Animate( ):
glutSetWindow( MainWindow );
glutPostRedisplay( );
// in Display( ):
// turn # msec into the cycle ( 0 - MSEC-1 ):
int msec = glutGet( GLUT_ELAPSED_TIME ) % MSEC;
// turn that into a time in seconds:
float nowTime = (float)msec / 1000.;
. . .
Pattern.SetUniformVariable( "uAd", Ad.GetValue( nowTime ) );
. . .
// a global:
float Ad;
// in the Keyboard( ) function:
case 'a':
Ad = some small value
break;
case 'A':
Ad = some larger value
break;
// in Display:
Pattern.SetUniformVariable( "uAd", Ad );
#version 330 compatibility
// will be interpolated into the fragment shader:
out vec2 vST; // texture coords
out vec3 vN; // normal vector
out vec3 vL; // vector from point to light
out vec3 vE; // vector from point to eye
out vec3 vMC; // model coordinates
// for Mac users:
// Leave out the #version line, or use 120
// Change the "out" to "varying"
const vec3 LIGHTPOSITION = vec3( 5., 5., 0. );
void
main( )
{
vST = gl_MultiTexCoord0.st;
vMC = gl_Vertex.xyz;
vec4 ECposition = gl_ModelViewMatrix * gl_Vertex; // eye coordinate position
vN = normalize( gl_NormalMatrix * gl_Normal ); // normal vector
vL = LIGHTPOSITION - ECposition.xyz; // vector from the point to the light position
vE = vec3( 0., 0., 0. ) - ECposition.xyz; // vector from the point to the eye position
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
}
In the fragment shader:
#version 330 compatibility
// you can set these 4 uniform variables dynamically or hardwire them:
uniform float uKa, uKd, uKs; // coefficients of each type of lighting
uniform float uShininess; // specular exponent
// in Project #1, these have to be set dynamically from glman sliders or keytime animations or by keyboard hits:
uniform float uAd, uBd;
uniform float uTol;
// interpolated from the vertex shader:
in vec2 vST; // texture coords
in vec3 vN; // normal vector
in vec3 vL; // vector from point to light
in vec3 vE; // vector from point to eye
in vec3 vMC; // model coordinates
// for Mac users:
// Leave out the #version line, or use 120
// Change the "in" to "varying"
const vec3 OBJECTCOLOR = vec3( ?, ?, ? ); // color to make the object
const vec3 ELLIPSECOLOR = vec3( ?, ?, ? ); // color to make the ellipse
const vec3 SPECULARCOLOR = vec3( 1., 1., 1. );
void
main( )
{
vec3 myColor = OBJECTCOLOR;
vec2 st = vST;
// blend OBJECTCOLOR and ELLIPSECOLOR by using the ellipse equation to decide how close
// this fragment is to the ellipse border:
int numins = int( st.s / uAd );
int numint = int( st.t / uBd );
<< do the rest of the ellipse equation to compute d >>
float t = smoothstep( 1.-uTol, 1.+uTol, ??? );
myColor = mix( ELLIPSECOLOR, OBJECTCOLOR, t );
// now use myColor in the per-fragment lighting equations:
vec3 Normal = normalize(vN);
vec3 Light = normalize(vL);
vec3 Eye = normalize(vE);
vec3 ambient = uKa * myColor;
float dd = max( dot(Normal,Light), 0. ); // only do diffuse if the light can see the point
vec3 diffuse = uKd * dd * myColor;
float s = 0.;
if( dd > 0. ) // only do specular if the light can see the point
{
vec3 ref = normalize( reflect( -Light, Normal ) );
float cosphi = dot( Eye, ref );
if( cosphi > 0. )
s = pow( max( cosphi, 0. ), uShininess );
}
vec3 specular = uKs * s * SPECULARCOLOR.rgb;
gl_FragColor = vec4( ambient + diffuse + specular, 1. );
}
If you are on a Mac, remove the #version lines (or use 120) and change "out" and "in" to "varying".
float t = smoothstep( 1. - uTol, 1. + uTol, results_of_ellipse_equation );Then use t in the mix function to blend the colors on the edge of the ellipse.
Obj snake.objor use the API and our LoadObjFile( ) function. the OBJ file needs to be in the same folder as your .cpp, .glib, .vert, and .frag files.
Use Canvas to turn in your:
Submissions are due at 23:59:59 on the listed due date.
| Feature | Points |
|---|---|
| Hard-edged elliptical dots | 10 |
| Smooth-edged elliptical dots by changing uTol | 20 |
| Correct elongation by changing uAd and uBd | 10 |
| Correct per-fragment lighting | 20 |
| Potential Total | 60 |