CS 520 Advanced Computer Graphics


Homework 3 Partial Solutions
Due March 11, 2009 ( Wed )

  1. ( 20 points ) Use whatever method you prefer, write a program that creates a scene consisting of a cube and a teapot sitting on a flat surface near each other; a fixed light source is shining from the direction ( 1, 1, 1, 0 ). Form shadows of the cube and the teapot on each other and on the flat surface. The program allows you to rotate the objects around the axis while keeping the light source fixed by pressing keys, 'x', 'X', 'y', 'Y', 'z' and 'Z'.

  2. (20 points ) Write a program that maps a texture of checkerboard image ( refer to lecture notes ) onto a sphere and a torus.

  3. ( 20 points ) Suppose you want to create bump mapping for a unit sphere which can be described by
      p( θ , φ ) = ( r sin &theta cos φ, r sin θ sin φ, r cos θ )
    where
    • r = radius = 1,
    • θ = angle from z-axis ( 0 ≤ &theta ≤ π ),
    • φ = angle from x-axis ( 0 ≤ φ ≤ 2π )
    Suppose
    • u = φ/2π
    • v = θ/π

    Find the following for a point p(u, v) in terms of u and v.

    • unit normal n(u,v) at p(u, v).
    • pu and pv,
    • If the surface is perturbed by a small amount d(u,v) in the normal direction, with d(u,v) = au + bv, find the new normal n'(u,v).

    Solutions:

      1) From the given conditions, we have r = 1, φ = 2πu, θ = πv and
      p(u, v) = ( sin πv cos 2πu, sin πv sin 2πu, cos πv )
      The unit normal at a point p of a unit sphere has the same component as the point (i.e. nx = x, ny = y, nz = z ). Thus,

      2) pu and pv are given by:

      3) Since d = a u + b v, we have

      and

      Evaluationg this, we obtain

  4. ( 20 points )Write a program that uses a vertex shader to morph one object into another. Besides morphing the vertices, morph other variables such as the colors of the vertices.

    Solutions:

    The vertex shader that morphs vertices is shown below. We use Vertex2 to pass in the vertices of the second object and use the built in mix() function to blend the two vertices.

    //morph.vert: morphing vertex
    
    uniform float t;        //value provided by application program
    attribute vec4 Vertex2; //vertex of second object
    
    void main(void)
    {
      //gl_vertex*(1-t) + Vertex2*t
      gl_Position = gl_ModelViewProjectionMatrix * mix(gl_Vertex, Vertex2, t );
    
    }
    	

    Your application should provide the blending factor t and Vertex2. The following is a sample code segment.

    float tValue;
    GLuint tParam;          //parameters for sending to vertex shader
    GLuint Vertex2Param;
    .....
    void init()
    {
      ....
      ....
      tParam = glGetUniformLocation ( programObject, "t" );
      Vertex2Param = glGetAttribLocation ( programObject, "Vertex2" );
    }
    
    //arbitrarily create two figures for demo use
    void makeFigures( float A[][3], float B[][3] )
    {
      A[0][0] = 0;   A[0][1] = 0;     A[1][0] = 3;     A[1][1] = 3;
      A[2][0] = 6;   A[2][1] = 0;     A[3][0] = 6;     A[3][1] = -6;
      A[4][0] = 4;   A[4][1] = -6;    A[5][0] = 4;     A[5][1] = -4;
      A[6][0] = 2;   A[6][1] = -4;    A[7][0] = 2;     A[7][1] = -6;
      A[8][0] = 0;   A[8][1] = -6;
      B[0][0] = 0;   B[0][1] = 0;     B[1][0] = 3;     B[1][1] = 0;
      B[2][0] = 6;   B[2][1] = 0;     B[3][0] = 6;     B[3][1] = -2;
      B[4][0] = 4;   B[4][1] = -2;    B[5][0] = 4;     B[5][1] = -6;
      B[6][0] = 2;   B[6][1] = -6;    B[7][0] = 2;     B[7][1] = -2;
      B[8][0] = 0;   B[8][1] = -2;
    }
    
    void display(void)
    {
      ....
      ....
       int N = 9;
       GLfloat A[N][3], B[N][3];
       makeFigures( A, B );
       glBegin ( GL_POLYGON );
       for ( int i = 0; i < N; ++i ) {
         glUniform1f ( tParam, tValue );
         glVertexAttrib3fv ( Vertex2Param,  &B[i][0] );     //send second object vertex toshader 
         glVertex2fv ( A[i] );                              //vertex of first object
       }
       glEnd();
       ....
    }
    	

  5. ( 20 points )Write a vertex program that will bounce a ball whose initial velocity and position are provided by the application program. Hint: You can use the reflect() function to compute the new direction of the ball after it hits the floor. Its vertical speed should be reduced by a constant value, the coefficient of restitutions, each time that it hits the floor.

    Solutions:

    This is a simple physics problem. Suppose the ground is at y = 0 and initially the ball is at height y = h0 with zero velocity and the gravitational acceleration is g. The time required for the ball to drop through distance h0 is given by

    t0 = √ ( 2 h0 / g ) The distance h travelled by the ball in time t with initial velocity u is

    h = u t - (g/2) t2 If h <= 0, it implies that the ball has hit the ground and needs to be bounced. On the other hand, the time to bounce a distance h0 and reach the ground again is

    t0 = 2 √ ( 2 h0 / g )

    Combining these, we can have vertex shader like the following.

    //bounce.vert
    
    uniform float time;             //value provided by application program
    attribute vec3 vel;             //value provided by application program
    
    void main(void)
    {
      float s = 1000.0;             //scale factor
      float g = 10.0;               //gravitational acceleration
      float t;
      float h, h0;                  //h0 = initial height
      float t0;
      float c = 0.9;                //coefficient of restitution
      t =  time / s;                //time in ms
    
      h0 = gl_Vertex.y;             //initial height of ball
      vec3 norm = vec3 ( 0, 1, 0 );
      vec3 vel1, vel2;
    
      t0 = sqrt ( 2 * h0 / g );     //time to reach ground
    
      vel1.x = vel.x;
      vel1.y = vel.y - g * t0;
      vel1.z = vel.z;
    
      //initial height is gl_vertex.y
      h =  h0 -  g/(2.0)*t*t;       //height of ball at time t
    
      while ( h <= 0  ){                            //ball should always be above ground
        vel2 = c * reflect ( vel1, norm );          //bouncing velocity reduced
        t = t - t0;
        h = vel2.y * t - g/(2.0) * t * t;
        h0 = c * h0;                                //reduced bouncing height
        t0 = 2 * sqrt ( 2 * h0 / g );               //time for one bounce
        vel1.y = vel2.y - g * t0;
      }
      gl_Position = gl_ModelViewProjectionMatrix * vec4 ( 0, h, 0, 1 );     //object_pos;
    }
            

    Extra Credit ( 10 points ) Use blender to create a short animated movie ( > 15 seconds ) that shows a 3-D chess piece moving around a chess board. Besides the demo, turn in a copy of the steps you have used to create it.

Make a demo to the instructor before or after a class or during the office hours. Progams must be able to be compiled and run in the machines of the lab.