CS 457/557 -- Winter Quarter 2025

Project #1

Step- and Blended-edged Elliptical Dots

60 Points

Due: January 19


This page was last updated: January 16, 2025


Requirements:

  1. Use GLSL and either glman or the GLSL API to render some geometry (your choice), covered with elliptical dots.

  2. Using a GLIB file (for glman) or using the GLSL API, use the following uniform variables:

    ParameterWhat It DoesDoes it have to be varied?
    uKaAmbient coefficientNo
    uKdDiffuse coefficientNo
    uKsSpecular coefficientNo
    uShininessSpecular exponentNo
    uAdEllipse diameter in sYes
    uBdEllipse diameter in tYes
    uTolWidth of the blend between ellipse and non-ellipse areasYes

  3. Remember that the border of an ellipse, defined in s and t coordinates is:
    (s-sc)2 / Ar2 + (t-tc)2 / Br2 = 1
    Be sure you compute the ellipse centers, sc and tc, correctly.

  4. The ellipse parameters must be set as uniform variables. If you are using glman, put them on sliders. If you are using the API, vary them using KeyTime animation or keybord hits.

    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
    
    

  5. If you are using the API, you could use KeyTime animation to show the effects of uAd, uBd, and uTol:
    
    // 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 ) );
            . . .
    

  6. Or, if you are using the API, you could use keyboard hits to show the effects of uAd, uBd, and uTol:
    
    // 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 );
    

  7. In the vertex shader, setup per-fragment lighting by doing something like this:
    #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".

  8. The uTol parameter is the width of a smoothstep( ) blend between the ellipse and non-ellipse areas, thus smoothing the abrupt color transition.
    
    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.

  9. The choice of geometry is up to you. Keep it simple at first (a sphere), then, if there is still time, feel free to get more creative. To try out one of the snake models, use the GLIB line:
    Obj snake.obj
    
    or 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.

Hints:


The Turn-In Process:

Use Canvas to turn in your:

  1. Your source files: .cpp, .glib, .vert, .frag, .geom
  2. A short PDF report containing:

  3. To see how to turn these files in to Canvas, go to our Project Notes noteset, and go the the slide labeled How to Turn In a Project on Canvas.

  4. Be sure that your video's permissions are set to unlisted.. The best place to set this is on the OSU Media Server.

  5. A good way to test your video's permissions is to ask a friend to try to open the same video link that you are giving us.

  6. The video doesn't have to be made with Kaltura. Any similar tool will do.

Submissions are due at 23:59:59 on the listed due date.

Grading:

FeaturePoints
Hard-edged elliptical dots10
Smooth-edged elliptical dots by changing uTol20
Correct elongation by changing uAd and uBd10
Correct per-fragment lighting20
Potential Total60