Skip to main content

Computer Graphics and Multimedia: Assignment 1

Computer Graphics and Multimedia
Assignment 1
    • Notifications
    • Privacy
  • Project HomeComputer Graphics and Multimedia
  • Projects
  • Learn more about Manifold

Notes

Show the following:

  • Annotations
  • Resources
Search within:

Adjust appearance:

  • font
    Font style
  • color scheme
  • Margins
table of contents
  1. Module 1
    1. Introduction to Computer Graphics with WebGL
    2. Assignment 1
    3. Assignment 2
  2. Module 2
    1. Working with WebGL and JavaScript
    2. Assignment 1
    3. Assignment 2
  3. Module 3
    1. Animation and Geometric Transformations
    2. Assignment 1
    3. Assignment 2
  4. Module 4
    1. Viewing and Projections
    2. Assignment 1
    3. Assignment 2
  5. Module 5
    1. Lighting and Shading
    2. Assignment 1
    3. Assignment 2
  6. Module 6
    1. Texture Mapping and Matrix Stacks
    2. Assignment 1
    3. Assignment 2
  7. Module 7
    1. Skyboxes and Shadow Maps
    2. Assignment 1
    3. Assignment 2
  8. Module 8
    1. Modeling and Hierarchy - Building Scenes
    2. Assignment 1
    3. Assignment 2

CS 4722 - Computer Graphics and Multimedia

Module #4, Assignment #1


Exercise #1

Modify the given CubeShade application so that it shows a shadow with the rotating cube:

The partial HTML code is given here: CubeShade.html.

The partial JavaScript code is given here: CubeShade.js.

Put the light source at postion (-4,4,0) and move the cube to position (0.7,0.7,0.0) and capture the shadow that falls on the x-z plane.


The first thing you need to do to create this effect is add three uniform mat4 matrices to the Vertex Shader, one called transMatrix, one called modelViewMatrix, and one called projectionMatrix.

Next, when calculating the value of gl_Position you need to multiply the three new matricies by the rotation matrices and then by vPosition as shown here:

    gl_Position = projectionMatrix * modelViewMatrix * transMatrix *
                                           rz * ry * rx * vPosition;


Next, in your Fragment Shader you will need to add the following as your third declaration:

    uniform bool useBlack;

Note: the first declaration in your Fragment Shader MUST ALWAYS BE the following line:

    precision mediump float;

Your program will not compile if that is not the first declaration.

Next, replace your "gl_FragColor = fColor;" line with the following:

        if (useBlack)
        {
            gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
        }
        else
        {
            gl_FragColor = fColor;
        }


Next, add the HTML buttons shown above, and have the handlers for them in your JavaScript code change the "axis" value accordingly.

In addition to this, you will need to make the following changes to your JavaScript code:


JavaScript code changes:

  1. You will need to add the following global variables to your JavaScript code:


    var near = 0.1;
    var far = 4;
    var left = -3.0;
    var right = 3.0;
    var ytop = 3.0;
    var bottom = -3.0;
    
    var fovy = 120.0;
    
    var transMatrix, transMatrixLoc;
    var modelViewMatrix, projectionMatrix;
    var modelViewMatrixLoc, projectionMatrixLoc;
    
    var useBlackLoc;
    
    var lightX = -4.0;
    var lightY = 4.0;
    var lightZ = 0.0;
    
    var cubeX = 0.7;
    var cubeY = 0.7;
    var cubeZ = 0.0;
    
    var vColor;
    
    var eye, at, up;
    var light;
    
    var shadowMV;
    


  2. And to your init() method, you will need to add the following code will set up the new matrices that you will be using:


        light = vec3(lightX, lightY, lightZ);
    
        // matrix for shadow projection
        shadowMV = mat4();
        shadowMV[3][3] = 0;
        shadowMV[3][1] = -1 / light[1];
    
        at = vec3(0.0, 0.0, 0.0);
        up = vec3(0.1, 1.0, 0.0);
        eye = vec3(-0.9, -1.0, 1.0);
    
        transMatrix = translate(cubeX, cubeY, cubeZ);
        transMatrixLoc = gl.getUniformLocation(program, "transMatrix");
        gl.uniformMatrix4fv(transMatrixLoc, false, flatten(transMatrix));
    
        modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
        projectionMatrixLoc = gl.getUniformLocation(program, "projectionMatrix");
    
        projectionMatrix = ortho(left, right, bottom, ytop, near, far);
        gl.uniformMatrix4fv(projectionMatrixLoc, false, flatten(projectionMatrix));
    
        useBlackLoc = gl.getUniformLocation(program, "useBlack");
        gl.uniform1i(useBlackLoc, false);
    


  3. And next, to your render() method, you need to replace the following line:

        gl.drawArrays(gl.TRIANGLES, 0, points.length);
    

    With the following set of lines:


        // model-view matrix for the square
        modelViewMatrix = lookAt(eye, at, up);
    
        gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(modelViewMatrix));
    
        gl.uniform1i(useBlackLoc, false);
    
        gl.drawArrays(gl.TRIANGLES, 0, points.length);
    
        // model-view matrix for the shadow
        modelViewMatrix = mult(modelViewMatrix, translate(light[0], light[1], light[2]));
        modelViewMatrix = mult(modelViewMatrix, shadowMV);
        modelViewMatrix = mult(modelViewMatrix, translate(-light[0], -light[1], -light[2]));
    
        // send color and matrix for shadow
        gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(modelViewMatrix));
    
        gl.uniform1i(useBlackLoc, true);
    
        gl.drawArrays(gl.TRIANGLES, 0, points.length);
    


Now you should be all done.



Exercise #2

Modify the given ShadowShear application so that it shows a shadow for the rotating objects using the a Shear matrix. Initially, your programs objects should look like the following:



The partial HTML code is given here: ShadowShear.html.

The partial JavaScript code is given here: ShadowShear.js.

After your modifications, each of the objects should cast a Shadow Polygon using a Shear matrix, like so:



HTML code changes:

  1. The first thing you need to do to create this effect is add the following two declarations to your Vertex Shader:

        uniform vec3 shearAng;
        uniform bool showShear;
    

    These values determine what is the shear angle and when to show it.


  2. Next, in your Main() method of your Vertex Shader, replace the following line:

        gl_Position = transMat * rz * ry * rx * scaleMat * vPosition;
    

    With the following conditional:

        if (showShear) {
            vec3 shearVec = atan( radians( shearAng ) );
            mat4 shear = mat4( 1.0, -shearVec.y, 0.0, 0.0,
                                0.0,  1.0, 0.0, 0.0,
                               -shearVec.z,  0.0, 1.0, 0.0,
                                0.0,  0.0, 0.0, 1.0 );
            gl_Position = transMat * shear * rz * ry * rx * scaleMat * vPosition;
        }
        else {
            gl_Position = transMat * rz * ry * rx * scaleMat * vPosition;
        }
    


  3. Next, in your Fragment Shader, add the following declaration:

        uniform bool useBlack;
    


  4. And then, once again, replace the following line:

        gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
    

    With the following conditional:

        if (useBlack)
        {
            gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );
        }
        else
        {
            gl_FragColor = fColor;
        }
    


In addition to this, you will need to make the following changes to your JavaScript code:


JavaScript code changes:

  1. You will need to add the following global variables to your JavaScript code:


    var shearAng = [0, 45, 90];
    
    var transMatCube2;
    var transMatOcta2;
    var transMatTetra2;
    
    var cubeOff2 = [0.1, -0.4, 0.5];
    var tetraOff2 = [0.8, -0.4, 0.5];
    var octaOff2 = [-0.6, -0.4, 0.5];
    
    var shearAngLoc;
    var showShearLoc;
    


  2. And to your init() method, you will need make the background color white.


  3. And to your init() method, you will need to add the following code that will set up new uniform values you will be sending to the shaders:


        transMatCube2 = translate(cubeOff2[0], cubeOff2[1], cubeOff2[2]);
        transMatTetra2 = translate(tetraOff2[0], tetraOff2[1], tetraOff2[2]);
        transMatOcta2 = translate(octaOff2[0], octaOff2[1], octaOff2[2]);
    
        shearAngLoc = gl.getUniformLocation(program, "shearAng");
        gl.uniform3fv(shearAngLoc, shearAng);
    
        showShearLoc = gl.getUniformLocation(program, "showShear");
        gl.uniform1i(showShearLoc, false);
    


  4. And next, to your render() method, you need to replace the "Render cube" code that has the following set of lines:

        // Render cube
        gl.uniformMatrix4fv(transMatLoc, false, flatten(transMatCube1));
        gl.drawArrays(gl.TRIANGLES, 0, totCubePts);
    


    With the following new set of lines for "Render Cube":


        // Render cube
        gl.uniformMatrix4fv(transMatLoc, false, flatten(transMatCube1));
        gl.uniform1i(useBlackLoc, false);
        gl.uniform1i(showShearLoc, false);
        gl.uniformMatrix4fv(scaleMatLoc, false, flatten(scalem(0.5, 0.5, 0.5)));
        gl.drawArrays(gl.TRIANGLES, 0, totCubePts);
    
        // Render cube shadow
        gl.uniformMatrix4fv(transMatLoc, false, flatten(transMatCube2));
        gl.uniform1i(useBlackLoc, true);
        gl.uniform1i(showShearLoc, true);
        gl.uniformMatrix4fv(scaleMatLoc, false, flatten(scalem(0.4, 0.4, 0.4)));
        gl.drawArrays(gl.TRIANGLES, 0, totCubePts);
    


    This new set of lines draws both the Cube and the Cube Shadow. Note how this new code turns off (makes them false) useBlackLoc and showShearLoc when making the Cube, and then it turns them on (makes them true) when making the Cube Shadow. And note how the scaleMatLoc has a scaling matrix with 0.5's for the Cube, and then it has a scaling matrix with 0.4's for the Cube Shadow.

    Now make the same type of changes to the "Render Tetrahedron" section and the "Render Octahedron" section, so that they also draw shadows for those objects as well.


  5. And for your final change you need to go back to the global declarations at the top of your JavaScript code and declare a variable called "useBlackLoc". Then, in the init() method you need to make it a location pointer for a uniform variable by assigning it to a "gl.getUniformLocation()" call, with "useBlack" as the uniform variable's name.


Now you should be all done.


Add a Comment block section to the top of your Javascript file in this assignment with the following information filled in using the following format:

/*
 * Course: CS 4722
 * Section: .....
 * Name: ......
 * Professor: ......
 * Assignment #: ......
 */

Be sure your program runs without error.

Deliverables

Turn in the files:

  • CubeShade.zip (with your HTML and JS files)
  • ShadowShear.zip (with your HTML and JS files)

Do this by uploading the file as an attachment to this Module's assignment drop box in D2L Brightspace.

Annotate

Next Chapter
Assignment 2
PreviousNext
Powered by Manifold Scholarship. Learn more at
Opens in new tab or windowmanifoldapp.org