CS 488: Lab 4 – Lit Cube
Welcome to lab, which is a place where you and your peers complete exercises designed to help you learn the ideas discussed in the preceding lectures. It is intended to be a time where you encounter holes in your understanding and talk out loud with your peers and instructor.
Your instructor will bounce around between breakout rooms to check in with you. However, you are encouraged to request assistance if you find your progress blocked.
Designate one of your group to be the host. This individual will be responsible for setting up a Live Share session in Visual Studio Code and submitting your work. No team member should dominate or be expected to carry the group. All members should be writing code and contributing ideas.
Setup
Host, follow these steps:
- Open Visual Studio Code.
- Click File / Open Folder, create a new folder, and open it.
- With the Live Share extension installed, select View / Command Palette, and choose Live Share: Start Collaborative Session.
- Copy the invitation link to your chat.
Non-hosts, join the session.
Task
Your task in this lab is to implement transformations via matrices. Follow these steps to complete this lab:
- Render a shaded cube using indexed geometry. Situate the cube in model space around the origin.
- Use an orthographic projection that reveals the entire cube and whose aspect ratio matches the viewport.
- Enable the depth test and back-face culling.
- Add a
keydown
listener that rotates the cube a some small number of degrees around the current x-axis when Up or Down are pressed and around the current y-axis when Left or Right are pressed. Consult theevent
parameter’skey
property to determine which key was pressed. Apply the new transformation after any existing transformation by concatenating it through matrix multiplication, as in this pseudocode:modelToWorld = newRotation * modelToWorld
By putting the new matrix as the left operand, it will be applied last. - Shade the cube using Lambertian or diffuse shading based only on normals and the direction to the light source. With the sphere, a surface’s normal could be derived from its position. That trick doesn’t work here. You’ll need to explicitly pass the normals as an additional vertex attribute. The four vertices on the right face have normals that point right. The vertices on the left face have normals that point left. The vertices on the front face have normals that point along the positive z-axis. If you stop and think about this, you’ll find that each of the cube’s eight vertices actually has three normals—because each vertex is at the corner of three faces. That’s a problem. The fix is treat the cube as six separate quadrilaterals. Your arrays might look something like this:
const positions = [ // positions for front face // positions for back face // positions for left face // positions for right face ... ]; const positions = [ // normals for front face // normals for back face // normals for left face // normals for right face ... ]; const indices = [ // indices for front face // indices for back face // indices for left face // indices for right face ... ];
- Implement the shading in world space by transforming the normal using the
modelToWorld
matrix. You will need to turn the normal into avec4
to make the multiplication work. The product will be avec4
. Convert the product back to avec3
before passing it along to the fragment shader by swizzling out the first three components:fnormal = product.xyz
. - Submit your
index.js
on Crowdsource. Enter the eIDs for your team members. If you need to make changes after you’ve already submitted, just reload the page and resubmit. If you haven’t finished by the end of the scheduled lab time, you are free to continue working. However, the submission must be made before the end of the day to receive credit.