| Module #4, Assignment #2
Exercise #1
Modify the given LookAtCube application so that it shows a cube starting with a Perspective projection of the cube instead of a Orthographic projection using a default FOVY value of 120, and it allows you to switch back and forth from Perspective to Orthographic projections, and to change the FOVY value, and the X and Y camera position:

To implement these changes, add the following controls:

The top buttons allow you to switch between Perspective Projection (i.e. Perspective View) and Orthographic Projection (i.e. Orthographic View).
On the next line the slider allows you to choose your FOVY value for the Perspective Projection, going from 60 to 160. Start your FOVY value at 120 and set the slider step to 10.
On the next line the buttons rotate the camera around the cube going left or right (with the x value rotating through the XZ plane). Start the angle at 0.7, and with each click of one of those buttons change the angle by 0.1 radians in that direction.
And on the last line the slider allows you to move the vertical view of the camera from a Y position of -2.0 up to a Y position of positive 2.0. Start your Y position at 1.0 and set the slider step to 0.1.
The partial HTML code is given here: LookAtCube.html.
The partial Javascript code is given here: LookAtCube.js.
The first change you need to make to create this effect is add two uniform mat4 matrices to the Vertex Shader, one called modelViewMatrix and one called projectionMatrix.
Next, when calculating the value of gl_Position you need to multiply the two new matricies by vPosition as shown here:
gl_Position = projectionMatrix * modelViewMatrix * vPosition;
Next, add the HTML controls that you need for this program as shown above.
In addition to this, you will need to make the following changes to your JavaScript code:
JavaScript code changes:
- You will need to add the following global variables to your JavaScript code:
var modelViewMatrix;
var modelViewMatrixLoc;
var projectionMatrix;
var projectionMatrixLoc;
var at = vec3(0.0, 0.0, 0.0);
var up = vec3(0.0, 1.0, 0.0);
var near = 0.1; //usually + .1 from the camera for perspective
var far = 4.0; //arbitrary
var left = -2.0;
var right = 2.0;
var ytop = 2.0;
var bottom = -2.0;
var fovy = 120.0;
var isPerspective = true;
var xAngle = 0.7;
var yValue = 1.0;
- And to your init() method, you will need to add the following code will set up the new matrices that you will be using:
modelViewMatrixLoc = gl.getUniformLocation(program, "modelViewMatrix");
projectionMatrixLoc = gl.getUniformLocation(program, "projectionMatrix");
projectionMatrix = perspective(fovy, 1.0, near, far);
gl.uniformMatrix4fv(projectionMatrixLoc, false, flatten(projectionMatrix));
- Also in your init() method, you will need to add the appropriate handlers for each of your HTML controls.
- Finally, in your render() method, you will need to add the following code above your gl.drawArrays( ... ) line:
var eye = vec3(Math.sin(xAngle), yValue, Math.cos(xAngle));
modelViewMatrix = lookAt(eye, at, up);
gl.uniformMatrix4fv(modelViewMatrixLoc, false, flatten(modelViewMatrix));
Now you should be all done.
Exercise #2
Modify the HatShapeRotate program so that it has buttons added so that you can rotate the camera around the entire hat shape (which is actually a 3D sinusoidal object) using either an Orthographic Projection or a Perspective Projection:

The following are the only controls you are to use to rotate the camera around the entire object going left or right, and up or down.

The partial HTML code for the HatShapeRotate program is given here: HatShapeRotate.html.
The partial Javascript code is given here: HatShapeRotate.js.
The first thing you need to do is add your six buttons with the appropriate labels to your HTML code below your canvas.
In addition to this, you will need to make the following changes to your Javascript code:
Javascript code changes:
- Most of your Javascript code has been given to you. For instance, you already have the theta angle declared, which is your horizontal angle of rotation through the x and z axes. But your program will also rotate vertically through the y axis, so you will need to declare another angle variable, called something like phi. In all, there are three new variables you should declare that have not been declared for you:
var phi = 0.0; // vertical angle of rotation
var fovy = 37; // frame of view angle for perspective view
var isOrtho = true; // flag to indicate current projection type
- Next, in your init() method, you will have to add your six button handlers. The "Rotate Right" and "Rotate Left" button handlers should add or subtract 0.1 from the value of theta while the "Rotate Up" and "Rotate Down" button handlers should add or subtract 0.1 from the value of phi. And your "Orthographic" and "Perspective" buttons should appropriately alter the value of isOrtho".
- All except one of your final changes need to be made in the render() method, but before you can make these changes you need to understand how the theta and phi angles determine the x, y and z coordinates of where the camera "eye" is.
As you move through the angle theta horizontally, you are sweeping through an angle on a plane of the the x and z axes (in yellow), rotating around the y axis:

This angle puts the camera at the x-coordinate that is equal to: radius * cos( θ ). And it puts it at the z-coordinate that is equal to: radius * sin( θ ):

When you add the vertical movement to the camera with the angle phi sweeping through the y axis (in blue) you move vertically:

This vertical motion moves the camera along the y-axis in the amount of: radius * sin( ϕ ).
But it also affects the x and z axes as well by multiplying cos( ϕ ) to whatever the x and z values were as determined by the theta ( θ ) angle above:

Another issue you must consider is that when the camera is moving vertically through the angle phi ( ϕ ), the up direction changes from the point of view of the person looking through the camera lens. The up direction is toward the positive y axis until it reaches 90 degrees (which is PI/2 in radians). At that point the up direction is toward the negative y axis. And it stays that way until it reaches 270 degrees (which is 3 * PI / 2 in radians), at which point the up direction once again goes toward the positive y axis, as shown here:

This all means that you will need to change the value of the up vector during the movement of the camera, so it can no longer be a constant. So go to the declaration area of the program and find the line:
const up = vec3(0.0, 1.0, 0.0);
And change that line to the line:
var up = vec3(0.0, 1.0, 0.0);
With this change and this information, it is now possible to finish the render() method:
- Inside the render() method, before the line that sets the value of the eye vector with "var eye = vec3( ... );", you need to deal with the issue of which direction is up pointing in. To make things simpler, lets make sure theta and phi, which are both in radians, stay between the value of 0 and 2 * PI with the following code:
if (theta > 2 * Math.PI)
theta -= 2 * Math.PI;
if (theta < 0)
theta += 2 * Math.PI;
if (phi > 2 * Math.PI)
phi -= 2 * Math.PI;
if (phi < 0)
phi += 2 * Math.PI;
- Next, still before the line that sets the value of the eye vector with "var eye = vec3( ... );", put another if statement that tests the value of phi and if it is greater than or equal to PI/2 AND if it is less than 3 * PI/2, then set the up vector equal to the negative y-direction:
vec3(0.0, -1.0, 0.0)
Otherwise (else), set the up vector equal to the positive y-direction:
vec3(0.0, 1.0, 0.0)
- Next, modify the "var eye = vec3( ... );" statement that is on three lines, and instead make the eye vector have the following (x,y,z) vector value:
- The x value should equal: radius * cos( θ ) * cos ( ϕ ).
- The y value should equal: radius * sin ( ϕ ).
- The z value should equal: radius * sin( θ ) * cos ( ϕ ).
These values are the same as the ones discussed above that were illustrated in the diagrams.
- Next, add an if statement above the line:
projectionMatrix = ortho(left, right, bottom, ytop, near, far);
If isOrtho is true, then the above line should run.
But if isOrtho is not true, then instead run a line that will set the projectionMatrix to a call to the perspective method, and pass it fovy as the first argument, 1.0 as the second argument, near as the third argument, and far as the last argument.
- Now you should be all done.
Add a Comment block section to the top of your Javascript program 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.
DeliverablesTurn in the files: LookAtCube.zip (with your HTML and JS files) HatShapeRotate.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.
|