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 |